<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 Jun 22, 2016, at 3:14 PM, Jordan Rose <<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Jun 22, 2016, at 13:05, Matthew Johnson <<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 22, 2016, at 12:59 PM, Jordan Rose <<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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;"><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 class="" style="word-wrap: break-word;"><div class=""><span class=""><div class=""><br class=""></div></span><div class="">I would really like to see submodules, but I think there would still be valid uses for `fileprivate` even with them. But of course we would need to know the details of submodules to have a good discussion about that so it’s a topic for the future. :)</div></div></div></blockquote><div class=""><br class=""></div><div class="">I wonder what became of this: <a href="https://github.com/apple/swift/blob/master/docs/Modules.rst#id18" class="">https://github.com/apple/swift/blob/master/docs/Modules.rst#id18</a></div></div></div></div></div></blockquote><br class=""></div><div class="">As the author of that document, it became clear (or maybe “it became murky”) that everyone wants different things from submodules, both for compiling their own targets and for importing other people’s targets. I’d almost suggest avoiding the word if you want to propose any of myriad features related to them:</div></div></div></blockquote><div class=""><br class=""></div>Interesting. The reason I like the idea of submodules is because I think they could accomplish several of these goals with a single feature in a more elegant manner and without introducing nearly as much complexity as would likely be present with independent features. </div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""></div><div class="">- importing a subset of APIs</div><div class="">- having APIs not imported by default with the top-level module</div></div></div></blockquote><div class=""><br class=""></div><div class="">Aren’t these kind of duals of each other (subsets of APIs being submodules, possibly with some APIs directly in the root module)?</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Most Clang submodules allow importing a subset of APIs, but still import everything by default with the top-level module. Explicit submodules are the exception rather than the common case.</div></div></div></blockquote><div><br class=""></div><div>That makes sense.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">- C++ namespacing within a module</div></div></div></blockquote><div class=""><br class=""></div><div class="">This is perhaps the most straightforward goal, but I believe it would be better served by a more robust submodule feature rather than being a limited namespace feature (for example, integrating with the subset import mentioned above).</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">- C++ namespacing within another module</div></div></div></blockquote><div class=""><br class=""></div><div class="">Can you elaborate? Do you mean namespaces that are “open to extension” in any module similar to how we can extend types from imported modules, provide retroactive conformances, etc? If that is what you mean I am not at all convinced there is value in this.</div></div></div></div></blockquote><div class=""><br class=""></div></div><blockquote class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="">import Foo</div></div><div class=""><div class="">Foo.Bar.baz()</div></div></blockquote><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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;"><br class=""></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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; float: none; display: inline !important;" class="">It’s not obvious that a namespace within the main module (the module currently being compiled) shouldn’t be flattened when the module is published—say, if things are only broken up for compilation time purposes. Alternately, it’s not obvious that the namespaces within a module match up to the units you want to be able to import as submodules.</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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;"></div></blockquote><div><br class=""></div><div>This is interesting. I suppose internal namespaces that are flattened could make sense in very large modules. That is something I hadn’t considered. It feels orthogonal to submodules to me but is certainly related.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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;"><div class=""><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">- breaking up compilation units (i.e. not compiling the entire module as one unit)</div></div></div></blockquote><div class=""><br class=""></div><div class="">This feels like it could be a build setting independent of submodules. For example, if you want WMO to span all submodules you wouldn’t necessarily want this, but if WMO isn’t important maybe you do.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">People mostly want this for compile time.</div></div></div></div></blockquote><div><br class=""></div><div>Right. But the ability to make a tradeoff between compile time and runtime performance feels more like a build setting of some kind (to me) rather than semantics of a language feature.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">- adding another access level between internal and fileprivate.</div></div></div></blockquote><div class=""><br class=""></div><div class="">This obviously makes sense in the context of a submodule (or namespace) feature, but feels (to me) like it would be awkward as an independent feature. </div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">- adding another access level between fileprivate and private.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Are you thinking of a file that contains scopes from different submodules? I’m trying to think of how this would do something that the new `private` wouldn’t already be able to do.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">A few people would prefer to break a file up into (disjoint) groups rather than have groupings across files. I personally think this would not be a good feature, but it goes on the list.</div></div></div></div></blockquote><div><br class=""></div><div>Yes, but I don’t understand why the new `private` wouldn’t accomplish the goal access control in this context. Here’s a strawman example:</div><div><br class=""></div><div>submodule Foo {</div><div> private func bar() { … }</div><div> // bar is only visible inside the scope introduced by `submodule Foo`</div><div>}</div><div><br class=""></div><div>What do you have in mind that wouldn’t be possible given some kind of syntax like that?</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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;"><div class=""><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">- something else?</div></div></div></blockquote><div class=""><br class=""></div><div class="">The big ones IMO are API subsets, namespaces, and encapsulation (access control) which feel like they fit very nicely together as a single elegant submodule feature.</div></div></div></div></blockquote><br class=""></div><div class="">“80% of the users only need 20% of the features, but everybody uses a different 20%”.</div><div class=""><br class=""></div><div class="">I’d be happy to have one feature that serves multiple purposes; however, in any such proposal I don’t want to take<span class="Apple-converted-space"> </span><i class="">any</i> behavior as obvious, because in the last three years someone has at one point asked for the opposite. :-)</div></div></div></blockquote><div><br class=""></div><div>Sure. You’ve certainly had a lot more experience exploring and discussing this area than I have! :) </div><div><br class=""></div><div>I still think it would be worthwhile to have a community discussion on the topic (at the right time of course) and see if we can’t find a balance that is workable.</div><div><br class=""></div><div>Matthew</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 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;"><div class=""><br class=""></div><div class="">Jordan</div></div></div></blockquote></div><br class=""></body></html>