<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 12, 2014, at 7:54 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" class="">richard@metafoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Nov 12, 2014 at 7:24 PM, Argyrios Kyrtzidis<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:kyrtzidis@apple.com" target="_blank" class="">kyrtzidis@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><div class=""><div class="h5"><blockquote type="cite" class=""><div class="">On Nov 12, 2014, at 6:42 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank" class="">richard@metafoo.co.uk</a>> wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Nov 12, 2014 at 2:53 PM, Argyrios Kyrtzidis<span class=""> </span><span dir="ltr" class=""><<a href="mailto:kyrtzidis@apple.com" target="_blank" class="">kyrtzidis@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 12, 2014, at 2:34 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank" class="">richard@metafoo.co.uk</a>> wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 11, 2014 at 8:04 PM, Argyrios Kyrtzidis<span class=""> </span><span dir="ltr" class=""><<a href="mailto:kyrtzidis@apple.com" target="_blank" class="">kyrtzidis@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 11, 2014, at 7:38 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank" class="">richard@metafoo.co.uk</a>> wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 11, 2014 at 6:49 PM, Argyrios Kyrtzidis<span class=""> </span><span dir="ltr" class=""><<a href="mailto:kyrtzidis@apple.com" target="_blank" class="">kyrtzidis@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 11, 2014, at 6:37 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank" class="">richard@metafoo.co.uk</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 11, 2014 at 3:45 PM, Argyrios Kyrtzidis<span class=""> </span><span dir="ltr" class=""><<a href="mailto:kyrtzidis@apple.com" target="_blank" class="">kyrtzidis@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><span class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 11, 2014, at 12:34 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank" class="">richard@metafoo.co.uk</a>> wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 11, 2014 at 10:00 AM, Argyrios Kyrtzidis<span class=""> </span><span dir="ltr" class=""><<a href="mailto:kyrtzidis@apple.com" target="_blank" class="">kyrtzidis@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Nov 10, 2014, at 7:48 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank" class="">richard@metafoo.co.uk</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Mon, Nov 10, 2014 at 4:00 PM, Argyrios Kyrtzidis<span class=""> </span><span dir="ltr" class=""><<a href="mailto:kyrtzidis@apple.com" target="_blank" class="">kyrtzidis@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class="">Hi all,</div><div class=""><br class=""></div><div class="">For frameworks Clang currently supports adding a separate module map file for the private headers of the framework. It looks specifically for the presence of ‘module.private.modulemap’ inside the .framework and parses both the public and the private module maps when it processes its module. We would like to extend support for private module maps for non-framework headers as well. </div><br class="">In the Darwin platform, the public SDK headers are located in '/usr/include', while the associated private SDK headers are located in '/usr/local/include’. '/usr/local/include’ comes before '/usr/include’ in the header search paths.<br class=""></div></blockquote><div class=""><br class=""></div><div class="">I worry that this will be fragile. If for any reason we look in /usr/include but not in /usr/local/include, we'll not load the private extension map and things will probably go quite badly from that point onwards. If the presence of the /usr/local/include headers is a fundamental part of a /usr/include module, then it seems better to me to specify that within the /usr/include module map.</div><div class=""><br class=""></div><div class="">So here's one possibility: allow 'extern module' declarations to be nested within other modules, then write your /usr/include module map as:</div><div class=""><br class=""></div><div class="">module MyModule {</div><div class=""> <span class=""> </span><...></div><div class=""> <span class=""> </span>extern module SomethingPrivate "/usr/local/include/module.private.map"</div><div class="">}</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">This has drawbacks:</div><div class=""><br class=""></div><div class="">- Details of the private SDK, “leak out” to the public one. It should work similar to frameworks, in that the public SDK remains the same irrespective if there is or not a private API, and the private API is a straight addition on top of the public one without needing to modify something in the public SDK.</div><div class="">- It is a bit weak as guarantee anyway because the public module map must necessarily function even when the extension map is missing, which means pointing at the wrong path or missing the private map when you really need it will not be detected.</div><div class="">- Flexibility to extend a module from any path may be valuable for testing.</div></div></div></blockquote><div class=""><br class=""></div><div class="">OK, I'm not sure I understand what problem you're solving. If the /usr/local/include stuff works as a layer on top of /usr/include, why do you need them to be built as part of the same module? (Do your /usr/local/include headers override / #include_next some of the /usr/include headers, perhaps? If so, do you need the #includes in /usr/include to find the /usr/local/include headers rather than the /usr/include headers?)</div></div></div></div></div></blockquote><div class=""><br class=""></div></div></span>There are some cases of cycles between public/private headers which would be accommodated by a single module build but the primary motivation is that we would like the module public/private interface to be under the same namespace, so you’d do<div class=""><br class=""></div><span style="white-space: pre-wrap;" class="">        </span>@import Dispatch;<br class=""><span style="white-space: pre-wrap;" class="">     </span>@import Dispatch.Private;<br class=""><br class=""><span style="white-space: pre-wrap;" class="">        </span>@import Darwin.POSIX.Foo.Bar;<br class=""><div class=""><span style="white-space: pre-wrap;" class="">   </span>@import Darwin.POSIX.Foo.Bar.Private;</div><div class=""><br class=""></div><div class="">and generally any kind of private extension:</div><div class=""><br class=""></div><div class=""><span style="white-space: pre-wrap;" class="">        </span>@import Dispatch.SuperCoolButPrivate;</div></div></blockquote><div class=""><br class=""></div><div class="">Do you want / need them to be built as a single module file, or not?</div></div></div></div></div></blockquote></div><div class=""><br class=""></div></div></div>As I said, cycles may make things difficult for separate module files, but how are we going to get new submodules under the same module name with separate module files ?<br class=""></div></blockquote></div><br class=""></div><div class="gmail_extra">Well, the restriction that module files correspond to top-level module names is arbitrary and artificial. (It's also a bad idea for a few reasons. It makes incremental refactoring very hard, for instance, because you're required to have no cycles at any point between things in different top-level modules.)</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Splitting up the description of how to build a module file across various module maps seems like a very error-prone strategy, especially if you're intending to be able to stop looking before you've read all of the relevant module maps.</div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">I think that the high level parts of my proposal are not dependent on whether we build one .pcm file or multiple ones, this is an implementation detail.</div><div class="">To be more specific, if we have </div><div class=""><br class=""></div><div class=""><div style="margin: 0px;" class=""><b class="">module.private.modulemap<span class=""> </span></b><span class="">(extension):</span></div><div style="margin: 0px;" class=""><span class="">extern module Dispatch</span></div><div style="margin: 0px;" class="">module Dispatch.Private {</div><div style="margin: 0px;" class=""> <span class=""> </span><headers></div><div style="margin: 0px;" class="">}</div><div class=""><br class=""></div></div><div class=""><div style="margin: 0px;" class=""><b class="">module.modulemap:</b></div><div style="margin: 0px;" class="">module Dispatch {</div><div style="margin: 0px;" class=""> <span class=""> </span><headers></div><div style="margin: 0px;" class="">}</div><div class=""><br class=""></div></div><div class="">It is an implementation detail whether we buiild one Dispatch.pcm file or a Dispatch.Private.pcm file that depends on another Dispatch.pcm; it should make no difference on user code.</div><div class="">Is this incorrect ?</div></div></div></blockquote><div class=""><br class=""></div><div class="">Whether we build one .pcm or multiple is observable in some circumstances. 1) We concatenate together all the header files built as part of one .pcm file, and parse them all at once, and that is not always semantically equivalent to building them in two separate passes. 2) If you have one big Dispatch.pcm file which also contains the private bits, and by any sequence of events you end up also pulling in another Dispatch.pcm that contains the public headers but not the private ones, you may get ambiguity errors. 3) We do not allow circular references across .pcm files but do allow them within a .pcm file.</div></div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">(2) is a bug.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Perhaps. Suppose I put this in a header:</div><div class=""><br class=""></div><div class="">extern struct {</div><div class=""> <span class="Apple-converted-space"> </span>int a, b;</div><div class="">} s;</div><div class=""><br class=""></div><div class="">If that ends up in two different translation units, do I have an error? In C++, the answer is "yes", because the types are different; in C, it's "no", because the types are compatible. Extending this to the modules world, if I have the above in two different modules, should they be mergeable?</div><div class=""><br class=""></div><div class="">With the "bottom-up modularization" approach that Apple has been taking so far, I expect you'll find that merging a Dispatch.pcm and a DispatchWithExtensions.pcm together won't work very well. (Ironically, I'd have more confidence this would work if you were using C++ rather than C, because the merging story is more developed and better tested there.) And even if it does work, the possibility of having two different modules providing the same interface as part of the same translation unit seems like a bad idea.</div></div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> Dispatch.pcm and Dispatch[WithExtensions].pcm will never show up in the same translation unit, they will have different identities; similar to how module maps from different paths result in different pcm files for the same module, and they are not mixed together in the same translation unit.</div></div></div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Consider the following:</div><div class=""><br class=""></div><div class="">"d.h" is in Dispatch, and "dx.h" is in DispatchWithExtensions.</div><div class="">Module M1 says '#include "d.h"'. We implicitly load only the /usr/include module map, find the Dispatch module, and build it, without ever loading the extension.</div><div class="">Module M2 says '#include "dx.h"'. That results in us building the DispatchWithExtensions module.</div><div class="">Now suppose a translation unit imports M1 and M2. We end up with both .pcm's in the same TU. <br class=""></div><div class=""><br class=""></div><div class="">How does your approach prevent the above from happening?</div></div></div></div></div></blockquote><div><br class=""></div><div>Do you mean that M1 and M2 are built from different translation units with different sets of search paths ? Or are they built with the same search paths ?</div><div>If they are built with the same search paths then they will both build and depend on the Dispatch[WithExtensions] module file. During header lookup for '#include "d.h”’ we will be parsing the module maps in the search paths, even in the paths that do not contain “d.h” (clang already does this). When we complete the Dispatch module definition it will be a definition that includes the extensions.</div><div><br class=""></div><div>If M1 and M2 are built with different search paths then the translation unit that imports both will rebuild M1 because it doesn’t depend on the expected Dispatch-<hashWithExtensions>.pcm.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">I think you should choose: either (a) if there's a private extension, then you somehow guarantee that you only ever build / use the .pcm with that extension and never mix that with a .pcm built without the extension, or (b) treat the private extension as a layer on top of the public module.</div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">If your Dispatch.Private is simply a layer on top of Dispatch, then building them as two separate .pcm files seems like the right choice; it keeps your Dispatch module (for want of a better word) modular. If on the other hand, you need includes/imports in Dispatch to pull in headers / submodules from Dispatch.Private, then one big Dispatch .pcm is probably the right answer, and we'd need something like your proposal so we could say "here is a Dispatch module that's like the one in /usr/include but different in the following ways”.</div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">(Whichever of these options we pick, we can make the "@import Dispatch.Private" syntax do the right thing.)</div></div></div></div></div></blockquote></span></div><div class=""><br class=""></div><div class=""><div class="">In both cases we would need to extend module map parsing to allow submodule extensions. I think the original proposal accommodates that with the possible need that once clang supports separating a top module to different pcm files that we may need to control whether there is a combined module file or multiple ones.</div><div class="">Given that separating a top module in multiple pcm files is a rather intrusive change and the combined pcm file is sufficient for our needs, I’d like to proceed for now with the extending module map functionality which will result in one top level .pcm file. Is this reasonable ?</div></div></div></blockquote></div><br class=""></div><div class="gmail_extra">A few questions:</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">What are you going to use as the defining module map file (part of the 'key' used for determining .pcm identity)? Is it the defining module map for the top-level module or the module map with the extension?</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">The key to determine identity will include both module map files.</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra">What happens if multiple module maps try to extend the same module?</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I’d prefer to allow it if they extend with different submodules, and error if they try to define the same submodule.</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra">Why do you need a separate module map file name? Why not just put your extension into the normal module.modulemap file?</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">The reason was to disallow module definitions in the private module map file:</div></div></div></blockquote><div class=""><br class=""></div><div class="">I don't think you need that if your 'extern module' specifies a path. You just imported a definition of the module; it'd be an error to provide another one.</div></div></div></div></div></blockquote><div><br class=""></div><div>Per my example, it protects against writing a module definition directly and missing any “extern” declaration (we could have “extern module” without a path also trigger an error if you define the extern'ed module in the same map file).</div><div><br class=""></div><div>In general I like that a ‘module.private.modulemap' would immediately indicate that it contains only private extensions to existing modules, while seeing a ‘module.modulemap’ you’d expect to see new module definitions. These can then be present in the same directory ('/usr/local/include/module.private.modulemap’ would contain the extensions while '/usr/local/include/module.modulemap’ would contain new modules that only exist in /usr/local/include).</div><div><br class=""></div><div>But I don’t think these are very important benefits; do you feel that it is unnecessary complexity ?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><div class=""><blockquote type="cite" class=""><div class="">- A module definition inside a private extension will be disallowed. The rationale is that otherwise <span class="">it will be a very common mistake for users to write</span></div><div style="margin: 0px; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px;" class=""><b class="">module.modulemap:</b></div><div style="margin: 0px;" class="">module Foo {</div><div style="margin: 0px;" class=""> <span class="Apple-converted-space"> </span><public headers></div><div style="margin: 0px;" class="">}</div><div style="margin: 0px; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px;" class=""><b class="">module.private.modulemap:</b></div><div style="margin: 0px;" class="">module Foo {</div><div style="margin: 0px;" class=""> <span class="Apple-converted-space"> </span><private headers></div><div style="margin: 0px;" class="">}</div><div style="margin: 0px; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px;" class="">and then be left scratching their heads wondering why things are broken (things missing, headers included textually, etc.). Being more strict in private extension maps will be beneficial.</div></blockquote><div class=""><div style="margin: 0px;" class=""><br class=""></div></div><div style="margin: 0px;" class=""><br class=""></div></div></span><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><br class=""></div><span class=""><div class="gmail_extra">Also note that 'extern module' takes a string literal pointing to the module map file defining the module, and it triggers us to recursively load that module map file; your approach doesn't seem to take this into account.</div></span></div></div></blockquote><div class=""><br class=""></div><div class="">I was aware of this functionality but if I think it is unnecessary boilerplate and restricted flexibility if we force all the authors to write module maps like:</div><div class=""><br class=""></div><div class="">extern module Dispatch "../../../usr/include/dispatch/module.modulemap"<br class=""><div dir="ltr" class=""><div class="gmail_extra">module Dispatch.Private { … }</div></div></div><div class=""><br class=""></div><div class="">The compiler is going to either find the module definition or error about it, so there’s not much benefit to be hardcoding paths; such hardcoding will restrict flexibility and make testing more cumbersome.</div><div class=""><br class=""></div><div class="">I’m not suggesting of course to remove the functionality, only to also allow "extern module Dispatch”.</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra">I think when we see</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra"> <span class="Apple-converted-space"> </span>extern module Foo "blah"</div><div class="gmail_extra"> <span class="Apple-converted-space"> </span>module Foo.Bar { ... }</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">... we should parse "blah" before parsing the extension (this is the natural result of the way the code is currently laid out) rather than waiting until we hit "blah" on the search path and then adding an extension to it.</div></div></div></blockquote></span></div><br class=""><div class="">Technically we don’t need to wait until we hit “blah". "extern module Dispatch” can create an ‘incomplete’ Dispatch module, the submodules will be added and once we parse the module definition, the module will be ‘complete’ (and module lookup will succeed).</div></div></blockquote></div></div></div></div></blockquote></div><br class=""></body></html>