<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=""><div class="">I think we're getting somewhere.</div><br class=""><div><blockquote type="cite" class=""><div class="">On 21 Jul 2016, at 12:01, Robert Widmann <<a href="mailto:rwidmann@apple.com" class="">rwidmann@apple.com</a>> wrote:</div><div class=""><div dir="auto" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""></div></div></blockquote></div></div></div></blockquote><div class=""><div dir="auto" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div></div></blockquote></div></div></div><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">(<a href="https://github.com/CodaFi/swift-evolution/blob/ab091043daa62158bd3337a2a2a467be3e16ff18/proposals/XXXX-qualified-imports.md#detailed-design" class="">An excerpt about the hiding directive</a>)</blockquote></blockquote></blockquote><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""></blockquote></blockquote><blockquote type="cite" class=""><div dir="auto" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="">4. Hmm, the above design detail is easily missed when reading the proposal. So what you're proposing is that the <i class="">hiding</i> of <font face="Menlo" class="">Date</font> essentially turns <span style="font-family: Menlo;" class="">Date</span> into a type that the code will know almost nothing about, except it's something we can pass to other types' methods that expect a <span style="font-family: Menlo;" class="">Date</span>, am I right?</div><div class=""><br class=""></div><div class="">What's the benefit in that? Do you anticipate it will make importing lighter somehow, possibly improving compilation or library loading speed? You mentioned something along those lines in the Motivation, but I'm not sure if I got it right here.</div></div></div></blockquote><div class=""><br class=""></div><div class="">It is so that use of an API in a framework like Foundation does not necessitate polluting your Swift files with a million using imports - thus defeating the purpose of this proposal.</div></div></div></blockquote><div><br class=""></div><div>You explained further below what else `hiding` imports can be used for. But my comment was motivated by your example of `<b style="font-family: Menlo;" class="">import</b><span style="font-family: Menlo;" class=""> Foundation </span><b style="font-family: Menlo;" class="">hiding</b><span style="font-family: Menlo;" class=""> (Date)</span>`. </div><div><br class=""></div><div>I fail to see how the lack of `<b class=""><font face="Menlo" class="">hiding</font></b>` imports would imply Swift files with a lot using imports. In my counting, they amount to at most one extra using import. (And I propose ~10 lines below what would get that to zero.)</div><div><br class=""></div><div>The simple reason I could see someone write `<font face="Menlo" class=""><b class="">import</b> Foundation <b class="">hiding</b> (Date)</font>` is because another imported module "<font face="Menlo" class="">Julian</font>" she uses happens to export another <font face="Menlo" class="">Date</font> type which she wants to use instead. And if we could just as well solve that use case by making it so that</div><div><br class=""></div><div><font face="Menlo" class=""> <b class="">import</b> Foundation</font></div><div><font face="Menlo" class=""> <b class="">import</b> Julian, Julian <b class="">using</b> (Date)</font></div><div><font face="Menlo" class=""> assert(Date.self == Julian.Date.self)</font></div><div><br class=""></div><div>brings in both modules but makes Julian.Date the one that Date is shorthand of.</div><div><br class=""></div><div>Besides, Joe and friends offered the use of `<font face="Menlo" class="">*</font>` to mean "and everything else", which is problematic because `<font face="Menlo" class="">*</font>` also happens to be an operator function name. But we could make it so that the underscore imports everything else (without explicit qualification), making the above example exactly equivalent to:</div><div><br class=""></div><div><div><font face="Menlo" class=""> <b class="">import</b> Foundation <b class="">using</b> (_) <font color="#919191" class="">// same as `import Foundation`</font></font></div><div><font face="Menlo" class=""> <b class="">import</b> Julian <b class="">using</b> (_, Date) <font color="#919191" class="">// bring in Date explicitly and all else implicitly</font></font></div><div class=""><div><font face="Menlo" class=""> assert(Date.self == Julian.Date.self)</font></div></div><div class=""><br class=""></div><div class=""><br class=""></div></div><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><div class="">DateFormatter alone needs to know about Date, String, TimeInterval, Calendar, Locale, and TimeZone. Each of those needs to know about additional components. To require an import decl to use these types explicitly would be madness. You'd just wind up importing Foundation anyway.</div></div></div></div></blockquote><div><br class=""></div><div>"<i class="">You'd just wind up importing Foundation anyway</i>" is an argument that doesn't seem imply from the given Motivation section AFAICT.</div><div><br class=""></div><div>I can see three kinds of problems here (objective or subjective), caused by importing the whole Foundation:</div><div><ol class=""><li class=""><b class="">Identifier name conflicts</b>, which we could solve with just the `import Module using (name, Name, _)` syntax, essentially indicating which Module should be preferred.<br class=""><br class=""></li><li class=""><b class="">Identifier names shadowing module names</b>, where e.g. a `<font face="Menlo" class=""><b class="">private enum</b> Foundation {}</font>` disables the fully qualified access to the Foundation module's API). This remains an unsolved problem, but the introduction of <i class="">qualified module imports</i> `<font face="Menlo" class=""><b class="">import</b> Foundation <b class="">as</b> Foundation</font>` or `<font face="Menlo" class=""><b class="">import</b> Foundation <b class="">as</b> F</font>` (or, heh, `<font face="Menlo" class=""><b class="">import</b> Foundation <b class="">as is</b></font>`) would be one way of going about it.<br class=""><br class=""></li><li class=""><b class="">Auto-completer "hygiene"</b>, or <b class="">being explicit</b> which part of a large imported API is <b class="">not</b> considered appropriate to use by the author.</li></ol></div><div>Point 3 is the only problem that `<font face="Menlo" class=""><b class="">hiding</b></font>` imports could be uniquely used for, especially if they can be narrowed down to members of imported types and extensions (e.g. <font face="Menlo" class="">Swift.String.UTF8View</font>, as given in the proposal). But is that worth having?</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="">5. These chaining rules do fit on the back of a napkin, but I'm not sure if we need them at all. I'm not convinced we need `<b class=""><font face="Menlo" class="">hiding</font></b>` imports, and without hiding imports, we need no rules for the order of imports.</div></div></div></blockquote><div class=""><br class=""></div>How else are we to allow you to import a using type but not any of its member types?</div></div></div></blockquote><div><br class=""></div><div>I don't know. I'm asking "why?" not "how?"</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class="">How could we support removing APIs related to NSCell in AppKit apps? How about NSStream everywhere else? How else can we allow, in the future, the ability to import NSObject but none of its KVO-related members?</div></div></div></blockquote><div><br class=""></div><div>I'm saying you should explain this in the Motivation. Or consider moving the `<b class=""><font face="Menlo" class="">hiding</font></b>` import syntax into a further proposal.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class="">A hiding import is an invariant: It says a particular API should never be considered for use in this file. The very act of 'using' an identifier means you are hiding all others. The very act of 'hiding' an identifier means you are using all others.</div></div></div></blockquote><div><br class=""></div><div>That is very logical. But it would be better if there was a real-world example use case given where the use of `<b class=""><font face="Menlo" class="">hiding</font></b>` was a clear win over a combination of `<font face="Menlo" class=""><b class="">import</b></font>` and `<font face="Menlo" class=""><b class="">import</b> ... <b class="">using</b> (...)</font>`. The current one about Date isn't very convincing because instead of hiding one, it could be solved by highlighting (using) the other.</div><div><br class=""></div><div><br class=""></div><blockquote type="cite" class=""><div dir="auto" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="">What I will keep suggesting is that `<font face="Menlo" class=""><b class="">using</b></font>` imports actually take up the name in the file-local scope such that nothing else in the same file's scope — be it another `<font face="Menlo" class=""><b class="">import</b> ... <b class="">using</b> (...)</font>`, a local type declaration, function, or value — can declare the same name with a different meaning. That way, a plain</div><div class=""><font face="Menlo" class=""><b class=""><br class=""></b></font></div><div class=""><font face="Menlo" class=""><b class=""> import</b> Foo</font></div><div class=""><br class=""></div><div class="">can import everything from <font face="Menlo" class="">Foo</font>, while another</div><div class=""><font face="Menlo" class=""><b class=""><br class=""></b></font></div><div class=""><font face="Menlo" class=""><b class=""> import</b> Foo <b class="">using</b> (Bar)</font></div><div class=""><br class=""></div><div class="">can be used to explicitly choose the <font face="Menlo" class="">Bar</font> the code is about to use.</div></div></div></blockquote><div class=""><br class=""></div>That was the plan. You will receive an "invalid redeclaration" error as always. </div></div></blockquote><br class=""></div><div>👍!</div><div><br class=""></div><div>— Pyry</div><div><br class=""></div></body></html>