<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 Jul 20, 2016, at 11:56 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">On Thu, Jul 21, 2016 at 1:40 AM, Robert Widmann <span dir="ltr" class=""><<a href="mailto:rwidmann@apple.com" target="_blank" class="">rwidmann@apple.com</a>></span> wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc 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 Jul 20, 2016, at 10:04 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">On Wed, Jul 20, 2016 at 10:33 PM, Robert Widmann<span class=""> </span><span dir="ltr" class=""><<a href="mailto:devteam.codafi@gmail.com" target="_blank" class="">devteam.codafi@gmail.com</a>></span><span class=""> </span>wrote:<br 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 dir="auto" class=""><div class=""><span class=""></span></div><div class=""><div class=""><br class=""><br class="">~Robert Widmann</div><div class=""><br class="">2016/07/20 19:01、Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> のメッセージ:<br class=""><br class=""></div><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Jul 20, 2016 at 8:10 PM, Robert Widmann<span class=""> </span><span dir="ltr" class=""><<a href="mailto:rwidmann@apple.com" target="_blank" class="">rwidmann@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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Jul 20, 2016, at 5:47 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Jul 20, 2016 at 6:30 PM, Robert Widmann<span class=""> </span><span dir="ltr" class=""><<a href="mailto:rwidmann@apple.com" target="_blank" class="">rwidmann@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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">“The Phase Distinction” is a semantic one, not one built into the import system itself.</div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I understand. To rephrase my question: why introduce this semantic distinction to Swift?</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">What I meant is that even the system I’m modeling this on makes a distinction between import directives that actually expose identifiers to modules and import directives that modify identifiers that are already in scope.</div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">This is, IMO, very complex. I appreciate enormously the conceptual simplicity of the current Swift approach which, for all of its deficiencies, has only one import directive that does what it says on the tin: it exposes identifiers. I'm not bothered if it gains the ability to expose identifiers differently from one file to the next without keywords firewalled from each other to preserve the notion of phases of import.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span>We are <i class="">not</i> changing the unqualified Swift import system. Take a gander at the proposal again, or even the first draft. Swift has a particularly strange syntax for qualified imports that hasn’t received attention since it was first introduced 2 major versions ago. That thing allows quite a variety of senseless variants that can be both completely expressed by and subsumed by `using` and `hiding`.</div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">My sense, which I think has been echoed by others, is that the proposed solution is syntactically complex, and now that I understand that you're thinking through a multi-phase concept, also conceptually multilayered. I'm not arguing that the existing syntax for qualified imports doesn't need changing, only that there is room for radical simplification of the proposed solution IMO. As I re-read this proposal once more, it strikes me that the motivating issues identified (needlessly specific, does not compose, etc.) don't clearly argue for the specific direction proposed as opposed to alternatives like Joe's.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Perhaps they need to reread the proposal. Syntactically complex how? We're introducing two keywords and using tuple syntax. Our grammar changes are laid bare and take up 7 lines. I think there might be a general air of confusing semantics changes with syntax changes.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I can't speak for the general air, but putting on my disinterested reader hat, I can see why the confusion might arise--</div><div class=""><br class=""></div><div class="">The Motivation section begins:</div><div class="">"The existing syntax for qualified imports..."</div><div class=""><br class=""></div><div class="">And the Proposed Solution begins:</div><div class="">"The grammar and semantics of qualified imports..."</div><div class=""><br class=""></div><div class="">But the Detailed Design begins:</div><div class="">"Qualified import syntax will be revised..."</div><div class=""><br class=""></div><div class="">It's neither here nor there in terms of the proposal content, but suffice it to say that if one strings together the topic sentences in your proposal, the overarching narrative to be gleaned here is: "The current syntax for qualified imports is no good; therefore, we revise the semantics of qualified imports by changing the syntax." Sure.</div><div class=""><br class=""></div><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 dir="auto" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" 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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" 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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">Ne’er the twain shall meet.</div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Yes, you explained this concept very clearly as it applies to Agda. But I just don't see why we should care to have this distinction. Yet you are very adamant about it. What am I missing?</div><div class=""><br class=""></div><div class=""><br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">We should care because that is precisely what the two operations<span class=""> </span><i class="">do</i>. `using` and `hiding` introduce things or remove things from scope which is a very different operation from taking something that is already in scope and giving it a new name.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Perhaps I'm not phrasing my question very cogently. Of course, if we are to have `using`, `hiding`, and `renaming`, we must observe the distinctions between them.</div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class="">If you don’t want to think of them as part of the same import process, think of them instead in terms of their Swift equivalents today. </div><div class=""><br class=""></div><div class="">import Foundation using (Date) == import struct Foundation.Date</div><div class="">import Foundation hiding (Date) == import Foundation; @unavailable(*, “…") typealias Date = Foundation.Date</div><div class="">import Foundation using (TimeInterval) renaming (TimeInterval, to: Time) == import typealias Foundation.TimeInterval; typealias Time = Foundation.TimeInterval</div><div class=""><br class=""></div><div class="">Notice how it takes two declarations to create a renaming? It is not simple to drop being explicit about which names are actually in scope and expect a renaming to just implicitly slip in a using declaration. Nor is it simple to imagine _ as some magical namespace that you can pack away unwanted definitions into. using and hiding are very physical things and the rules for their behavior should be obvious and unambiguous - the proposal contains some examples of valid and invalid declarations to help with that.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">The examples worry me, in fact. That we might need to contemplate the behavior of a statement such as `import Foo using () hiding () hiding () using () hiding ()` suggests it's perhaps a little over-engineered for the purpose. Why allow chaining of `using` and `hiding` anyway? The only example given is of a nested type, which suggests nesting would be the way to go:</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">We allow chaining specifically to avoid that nesting behavior. Let's break up that chained import line by line to see why</div><div class=""><br class=""></div><div class="">import Swift using (String, Int, Double, Character)</div><div class=""> <span class=""> </span>hiding (String.UTF8View)</div><div class=""><br class=""></div><div class=""><div class=""><span style="background-color:rgba(255,255,255,0)" class="">import Swift // Scope contains {all identifiers in Swift}</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class="">using (String, Int, Double, Character) // Scope contains {String.*, Int.*, Double.*, Character.*}</span></div><div class=""><span style="background-color:rgba(255,255,255,0)" class=""> <span class=""> </span>hiding (String.UTF8View) </span><span style="background-color:rgba(255,255,255,0)" class="">// Scope contains {{String.* - String.UTF8View.*}, Int.*, Double.*, Character.*}</span></div></div></div></div></blockquote><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 dir="auto" class=""><div class=""><div class=""><span style="background-color:rgba(255,255,255,0)" class=""><br class=""></span></div><div class="">We express the exact same example in a much more human-readable way. You can read this out loud in plain English if you don't believe me: "import everything in Swift that is in String, Int, Double, and Character except String.UTF8View"</div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I have to disagree with your reasoning here. Unless I'm mistaken, the readability we're most concerned with is that of the written text, not its spoken form.</div><div class=""><br class=""></div><div class="">Nesting is an almost exclusively _visual_ way of organizing text and it adds real clarity on the page. Of course, if your litmus test for readability is literally trying to read it out loud, you would conclude that nesting is inferior. However, you'd make that same conclusion about so many other choices in Swift syntax (take, for instance, `:` instead of `extends` or `->` instead of `returns`). I conclude, on the other hand, that Swift is clearly not aiming to be AppleScript-like in this respect.</div></div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">I disagree. Standard Library Swift reads left to right in a very carefully chosen and consistent manner - it has been refined on this list and by the team quite a lot to get it that way. You seem to think I’m arguing verbosity is the end goal (AppleScript?): I’m not. Clarity is the goal. It is unambiguous what you mean when you say </div><span class=""><div class=""><br class=""></div><div class="">import Swift using (String, Int, Double) hiding (String.UTF8View)</div></span></div></div></blockquote><div class=""><br class=""></div><div class="">Is it ambiguous to say `import Swift using (String hiding (UTF8View), Int, Double)`? </div></div></div></div></div></blockquote><div><br class=""></div><div>What happens when it is time to extend this proposal to members?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><div class="">This syntax fits well with the overall direction of the language itself. For example, I use whitespace here out of habit but here’s nothing stopping you from making these look like the (meta)function invocations they really are<br class=""></div></span><div class=""><br class=""></div><div class="">import Swift </div><div class=""> using(String, Int, Double) </div><div class=""> hiding(String.UTF8View)</div><span class=""><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing: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="">In the comments you've used the nested notation `{{String.* - String.UTF8View.*}, Int.*, Double.*, Character.*}` to explain what it is your proposed syntax means. I really do find that, with all the punctuation in it, clearer than the chained notation. Of course, written `(String hiding UTF8View), Int, Double, Character`, it would be clearer still.</div><div class=""><br class=""></div><div class="">Critically, it eliminates the possibility of absurd chains of `hiding () using () hiding () using ()`, which create many more ways to represent the same subset of imports than can a nested syntax.</div><div class=""><br class=""></div><div class=""><br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">If you wish to express this, why should the language stop you?</div></div></div></blockquote><div class=""><br class=""></div><div class="">Given two options for syntax, one where expressing this chain is never necessary or even possible, and another where it is possible and perhaps even necessary, the former wins in terms of clarity, no?</div></div></div></div></div></blockquote><div><br class=""></div><div>Yours does not exclude this possibility, it merely shuffles it around (unless you plan on banning the empty tuple. In which case, why?)</div><div><br class=""></div><div>import Swift using (String using(UTF8View hiding ()), Int hiding (), Double hiding())</div><div><br class=""></div><div>At this point we’re just circling around an edge case described in the proposal as ripe for a merge-by-diagnostic. </div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""> Or better yet: we can offer diagnostics about this case just as we can offer diagnostics for doubled imports or improperly nested imports. A big part of why this proposal exists is because the existing diagnostics around qualified imports are uninformative and unhelpful.</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-weight:normal;letter-spacing: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"><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 dir="auto" class=""><div class="">Now reread the chaining example in the proposal.<span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">```</div><div class="">import Swift using (String hiding (UTF8View), Int, Double)</div><div class="">```</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" 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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">A qualified import is defining a procedure to import a subset of identifiers. That’s it.</div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Right, and I think an entirely different way of thinking about this would be much easier to learn and teach. Whether using, hiding, and renaming are to be supported now, later, or never, my mental picture of how it fits together is quite simple:</div><div class=""><br class=""></div><div class="">Analogy--suppose I am a pickle merchant. I import Foo-branded pickles from vendor X. I must re-label them with the right nutritional information before I can sell in this country. I can have labels printed saying that they are Foo-branded pickles. I can have them branded as Bar-branded pickles. Or I can have the labels deliberately misprinted, and then these pickles will never see the light of day. Point is, each of these is an active choice; even if I sell these as Bar-branded pickles, it's not that these pickles reached the domestic market as Foo-branded pickles, after which I scratched out the label with a Sharpie. These pickles had no domestic brand until I gave it one.</div><div class=""><br class=""></div><div class="">Back to importing modifiers--I import type Foo from module X. In my code, I need to make a choice to call this type Foo, or Bar, or nothing at all. In other words, there is only one directive, importing, and I am importing `Foo as Foo`, `Foo as Bar`, or `Foo as _`. Meanwhile, `import X using Foo` or `import X.Foo` (whatever the color of the bikeshed) would just be a shorthand for `import X using Foo as Foo` or `import X.Foo as Foo`. In this conceptualization, if I choose to import Foo as Bar, it's not that I'm importing Foo into the scope, then changing the identifier to Bar. The only identifier it ever has in this scope is Bar.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">And I’m the one with the complex semantics? :)</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I'm just trying to put into words what I'm familiar with after working in other languages such as Python.<br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span>Python may not be the right mindset for this. Their import story is much simpler because of their module system and generally simpler programming model.</div><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class="">How about this:</div><div class=""><br class=""></div><div class="">Using and Hiding relate to each other the way && and || do for bools. If && can be said to “prefer to return false, but return true given no other alternative” and || can be said to “prefer returning true, but return false given no other alternative”, then hiding can be said to “prefer importing all identifiers unless told not to in specific instances” and using can be said to “prefer importing no identifiers unless told to in specific instances”. </div><div class=""><br class=""></div><div class="">import Module.Name using (A, B, C, …) === import Module.Name hiding (ALL_NAMES - {A, B, C, ...})</div><div class=""><div class="">import Module.Name hiding (A, B, C, …) === import Module.Name using (ALL_NAMES - {A, B, C, ...})</div><div class=""><br class=""></div><div class="">That seems a particularly simple explanation to me. Let me know if anything else is unclear.</div></div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Your mental framework is clear. It's one that's just not found in very many other languages. Many of these have import declarations (or similar) with simpler syntax, yet they seem to address at least some of the problems that motivate your proposal. I guess my question in the end is, why have you chosen Agda as the basis for qualified imports in Swift and not one of these other languages?</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I chose Agda because it's the only major language I could find that treated identifiers like notation and used its module system for<span class=""> </span><i class="">real</i><span class=""> </span>organization of code; it's just a name, it can change if you want it to. The entire language is flexible. You can redefine functions with just an =, you can give new syntactic transformations without having to write crazy macros or worrying about hygiene. You get so much support from the type system too that all of these features just work together and you can sit back and feel satisfied that your tools pushed you to write<span class=""> </span><i class="">good code. </i>I<i class=""> </i>wrote it with Agda in mind because they took the time to think about the interactions between modules, code, and scope in a way we just haven't had the time to yet.</div><div class=""><br class=""></div><div class="">Many of these imports have simpler syntax but don't chain so lose expressiveness (Java). Or may have simpler surface syntax but don't properly interact with a moduleless system (Python, Java). Or may have a simpler syntax and give way to ambiguities (Python) when used in Swift. Agda is unambiguous, scalable, extensible, and simple.</div><div class=""><br class=""></div><div class="">Please don't confuse what's new with what's complex. But at the same time if there are any unexplainable loopholes we should know about them. I just haven't heard much I couldn't point to the proposal about yet so I don't see a reason to change.</div><div class=""><div class=""><br class=""></div></div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Thanks for this insight. It's clear that you're aiming at a far richer system in the future. However, it's hard to gauge how far Swift will eventually scale/extend what you're proposing here. I don't think there's any denying that the solution you've chosen introduces more involved semantics and a more verbose syntax than what's strictly necessary to address the specific motivating problem you give in this particular instance. Without a better sense of the outer bounds of how far this system will eventually be pushed, it's hard to judge whether the eventual payoff will be "worth it." And without any mention of the grander plan, I suspect the feedback you're going to get will continue along the path of trying to tear away whatever you're trying to put in place for the future which is not discernibly necessary for solving the immediate problem at hand.</div><div class=""><br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">If you believe this proposal is not extensible then cite a particular example, otherwise I can only say that I can’t tell the future. The syntax presented here is inspired by a tiny, tiny fragment of a language with an incredibly rich import mechanism and module system. It’s unclear how much of that system fits with Swift current - we already tried to formalize quite a bit in the first draft. For right now, <i class="">this</i> proposal is trying to clean up a long-neglected part of the language. If you feel that we’ve failed in that regard then tell me. Otherwise I’m fine with my syntax being pulled in a different direction in future additive proposals. I just want to fix this part of the language before the window on source-breaking changes closes for a while.</div><div class=""><div class="h5"><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing: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><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 dir="auto" class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><br class=""></div></div><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Jul 20, 2016, at 4:17 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing: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, Jul 20, 2016 at 4:57 PM, Robert Widmann<span class=""> </span><span dir="ltr" class=""><<a href="mailto:rwidmann@apple.com" target="_blank" class="">rwidmann@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-style:solid;border-left-color:rgb(204,204,204);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 Jul 20, 2016, at 2:52 PM, Robert Widmann via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class=""><br class="">On Jul 20, 2016, at 2:35 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class=""><div class=""><br class=""><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">On Wed, Jul 20, 2016 at 4:24 PM, Robert Widmann<span class=""> </span><span dir="ltr" class=""><<a href="mailto:rwidmann@apple.com" target="_blank" class="">rwidmann@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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Jul 20, 2016, at 2:19 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Jul 20, 2016 at 4:06 PM, Robert Widmann<span class=""> </span><span dir="ltr" class=""><<a href="mailto:rwidmann@apple.com" target="_blank" class="">rwidmann@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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Jul 20, 2016, at 2:04 PM, Robert Widmann via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class=""><br class="">On Jul 20, 2016, at 1:59 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class=""><div class="">Why is hiding in-scope but renaming out-of-scope?</div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Because hiding and renaming can be used in combination to subset out APIs, not alter them.</div><br class=""></div></div></blockquote><div class=""><br class=""></div></span><div class="">I mistyped. Should be "Because hiding and using can be used in combination to subset out APIs, not alter them."</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Sure, I buy that.</div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class="">Both are additive to Swift,<span class=""> </span></div></blockquote><div class=""><br class=""></div><div class="">As part of this proposal, both are source-breaking.</div></div></div></blockquote></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I don't see how. If hiding were cut from the proposal, adding it later with even the exact syntax you propose should break no pre-existing code--am I wrong?</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Renaming the way we originally laid it out would certainly be additive. The way you have it laid out would overlap a bit with hiding, sure, but it is still additive and (IMO, but I’m probably among a tiny minority of users that has used a proof assistant’s syntax as the basis for a proposal!) a good thing to have.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Sorry, I fear I've incorrectly communicated the point I was trying to make. I'm not advocating here for inclusion of renaming as part of this proposal. I simply think that--even though I buy your claim that hiding and using both subset out APIs--hiding has more affinity with renaming and the two facilities probably ought to be considered together, whenever that is.</div><div class=""><br class=""></div><div class="">Thus, I'm suggesting that it would be feasible to postpone discussion of hiding until such future time as a fully fleshed out renaming scheme is proposed. A revamped source-breaking import syntax without either hiding or renaming could be put in place now, and future addition of hiding and/or renaming would not have to be source-breaking. Is there something wrong with this argument?<br class=""></div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">There is still a useful to distinction to be made between explicitly renaming an API and explicitly hiding an API. Scala’s syntax to rename to underbar is a convenient notation for that kind of thing, but it goes against making qualified imports explicit and it means that renaming necessarily has to import identifiers into scope as well as rename them. What the OP (maybe it was you, sorry if it was) meant by “equivalent” missed the point that </div><div class=""><br class=""></div><div class="">import Swift hiding (String)</div><div class=""><br class=""></div><div class="">doesn’t translate into</div><div class=""><br class=""></div><div class="">import Swift renaming (String, to: _)</div><div class=""><br class=""></div><div class="">it translates into</div><div class=""><br class=""></div><div class="">import Swift hiding () renaming (String, to: _)</div><div class=""><br class=""></div><div class="">Renaming introducing identifiers into scope seems like a phase-shift and is not something the verb “rename” implies should happen here. It’s an interesting little hole in Agda’s module system that you can use </div><div class=""><br class=""></div><div class="">open A hiding (xs) renaming (ys to zs)</div><div class=""><br class=""></div><div class="">to mean</div><div class=""><br class=""></div><div class="">open A using (A; xs; ys) renaming (ys to zs)</div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">Actually, scratch that. Their documentation explicitly mentions that hiding and renaming may not be mixed because of the phase distinction and recommend the using translation above as the way to go.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">This is very illuminating. I think I've rather misunderstood what it is you're proposing. I wonder if others did also.</div><div class=""><br class=""></div><div class="">The syntax you proposed seemed cumbersome to me because my mental model of importing (informed by my probably superficial understanding of vanilla procedural programming languages) has only one phase: importing. This is why I proposed radically simplifying the spelling. To me, all of these operations are just sugar on a single import phase, where "stuff" from outside the module is "brought into" the module, either with the same name ("using"), a different name ("renaming"), or no name ("hiding").</div><div class=""><br class=""></div><div class="">But what you're saying here--if I understand correctly--is that you're proposing a multi-phase import system, where the possible phases, which can be composed in varying orders, are "using", "hiding", and "renaming". This is much, much more elaborate than I had contemplated. So beyond the bikeshedding of syntax, I'd ask: why do we need this multi-phase model of importing?</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" 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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class="">and as has been argued by others, the former is a special case of the latter.<br class=""></div></blockquote><div class=""><br class=""></div><div class="">A special case that cannot cause large-scale file-relative changes to APIs. Renaming is primarily used in other languages that treat free functions as more canonical than we do, or allow operator definitions that can be used as notation.<span class=""> </span></div></div></div></blockquote></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I don't know about 'primary use,' but the most common use I've experienced in Python, for example, is the mundane task of importing module Foo2 as Foo.</div><div class=""> </div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">And I still want that kind of syntax. I just want to get the breaking changes out of the way to make room for it in the future.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Right. See above about my argument as to which parts of your proposal have to be source-breaking, and which don't.</div><div class=""> </div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" 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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="">In those cases, you often have your own notation you’d like to use. In Swift, such changes should be rare enough that if you can’t solve them with a disambiguating qualified import then you can just redeclare the identifier some other way (typealias, top-level let, wrapper class, whatever).</div></div></div></blockquote></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">You've already stripped out renaming of members from the proposal. I agree wholeheartedly. The only flavor of renaming I'm thinking of here is equivalent to a fileprivate typealias and hiding, which cannot be done in this version of the proposal because hiding always comes before typealiasing and you can't typealias what isn't imported. It isn't about altering APIs any more than a fileprivate typealias can be thought of as altering APIs.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">In the sense that you can’t use the original identifier if you rename it, it is an alteration. John brought up a great point about exporting these things and how it could be a potentially dangerous thing. Even used locally, there’s the potential for people to specify 500 lines of import renaming crap that has to be copypasta’d throughout the codebase to maintain that particular style - not a use-case I’ve ever seen, but the potential is there.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">This is, I think, a spurious argument. I can equally have 500 lines of private typealiased crap that has to be copypasta'd.</div><div class=""> </div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote"><div dir="ltr" class="">On Wed, Jul 20, 2016 at 15:55 Brandon Knope <<a href="mailto:bknope@me.com" target="_blank" class="">bknope@me.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="auto" class=""><div class=""></div><div class="">I meant is there any reason for requiring parentheses </div></div><div dir="auto" class=""><div class=""><br class="">On Jul 20, 2016, at 4:53 PM, Robert Widmann <<a href="mailto:rwidmann@apple.com" target="_blank" class="">rwidmann@apple.com</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class="">Renaming is out of scope for this proposal, that’s why.<div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jul 20, 2016, at 1:26 PM, Brandon Knope <<a href="mailto:bknope@me.com" target="_blank" class="">bknope@me.com</a>> wrote:</div><br class=""><div class=""><div dir="auto" class=""><div class=""></div><div class="">I prefer this 100x more</div><div class=""><br class=""></div><div class="">Is there any reason why this wouldn't work?</div><div class=""><br class=""></div><div class="">Brandon </div><div class=""><br class="">On Jul 20, 2016, at 4:13 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class="">Yeah, I'd be happy to lose the parentheses as well.<br class=""><br class="">In the last thread, my take on simplifying the proposed syntax was:<br class=""><br class="">```<br class="">import Swift using String, Int<br class=""><br class="">// or, for hiding:<br class="">import Swift using Int as _<br class="">```<br class=""><br class="">The key simplification here is that hiding doesn't need its own contextual keyboard, especially if we support renaming (a huge plus in my book), as renaming to anything unused (or explicitly to `_`) is what hiding is all about.<br class=""><div class="gmail_quote"><div dir="ltr" class="">On Wed, Jul 20, 2016 at 15:01 Brandon Knope <<a href="mailto:bknope@me.com" target="_blank" class="">bknope@me.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="auto" class=""><div class=""></div><div style="direction:inherit" class=""><br class=""></div><div class=""><br class="">On Jul 20, 2016, at 3:08 PM, Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">As Joe and others mentioned in the previous thread, this syntax could be greatly simplified in ways that resemble analogous facilities in other languages. In particular I think it's alarmingly asymmetrical that, in your proposal, `import Swift using (String)` imports *only* String while `import Swift hiding (String)` imports *everything but* String. This becomes evident when chained together:<div class=""><br class=""></div><div class="">```</div><div class="">import Swift using (String, Int)</div><div class="">// imports only String and Int</div><div class="">import Swift using (String, Int) hiding (String)</div><div class="">// imports only Int</div><div class="">import Swift hiding (String, Int)</div><div class="">// imports everything except String and Int</div><div class="">import Swift hiding (String, Int) using (String)</div><div class="">// imports *nothing*? nothing except String? everything except Int? confusing.</div><div class="">```</div><div class=""><br class=""></div><div class="">By contrast, Joe's proposed syntax (with some riffs) produces something much more terse *and* much more clear:</div><div class=""><br class=""></div><div class="">```</div><div class="">import Swift.*</div><div class="">import Swift.(Int as MyInt, *)</div><div class="">import Swift.(Int as _, *)</div><div class="">```</div></div></div></blockquote><div style="direction:inherit" class=""><br class=""></div></div><div dir="auto" class=""><div style="direction:inherit" class="">I really don't find this much clearer than the proposed one. The proposal reads much clearer. </div><div style="direction:inherit" class=""><br class=""></div><div style="direction:inherit" class="">Joe's syntax has a lot going on in my opinion.</div><div style="direction:inherit" class=""><br class=""></div><div style="direction:inherit" class="">For the proposal, do we really need the parentheses? It makes the syntax look heavier</div></div><div dir="auto" class=""><div style="direction:inherit" class=""><br class=""></div><div style="direction:inherit" class="">Brandon </div></div><div dir="auto" class=""><div style="direction:inherit" class=""><br class=""></div><div style="direction:inherit" class=""><br class=""></div><div style="direction:inherit" class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Jul 20, 2016 at 1:52 PM, Robert Widmann via swift-evolution<span class=""> </span><span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</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-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class="">Hello all,<div class=""><br class=""></div><div class="">I’d like to thank the members of the community that have guided the revisions of this proposal. We have decided to heed the advice of the community and break down our original proposal on modules and qualified imports into source-breaking (qualified imports) and additive (modules) proposals. As qualified imports is the change most suited to Swift 3, we are pushing that proposal now as our final draft.</div><div class=""><br class=""></div><div class="">It can be had inline with this email, on <a href="https://github.com/apple/swift-evolution/pull/440" target="_blank" class="">Github</a>, or <a href="https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6" target="_blank" class="">as a gist</a>.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class=""><br class=""></div><div class="">~Robert Widmann</div><div class=""><br class=""></div><div class=""><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class="">Qualified Imports Revisited</h1><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class=""><ul style="padding-left:2em;margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class=""><li class="">Proposal: <a href="https://gist.github.com/CodaFi/NNNN-first-class-qualified-imports.md" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">SE-NNNN</a></li><li style="margin-top:0.25em" class="">Authors: <a href="https://github.com/codafi" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">Robert Widmann</a>, <a href="https://github.com/griotspeak" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">TJ Usiyan</a></li><li style="margin-top:0.25em" class="">Status: <span style="font-weight:600" class="">Awaiting review</span></li><li style="margin-top:0.25em" class="">Review manager: TBD</li></ul></h1><h2 style="margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#introduction" style="color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1;background-color:transparent" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Introduction</h2><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class=""><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">We propose a complete overhaul of the qualified imports syntax and semantics.</p></h1><h2 style="margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#motivation" style="color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1;background-color:transparent" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Motivation</h2><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class=""><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">The existing syntax for qualified imports from modules is needlessly explicit, does not compose, and has a default semantics that dilutes the intended meaning of the very operation itself. Today, a qualified import looks something like this</p><div style="margin-bottom:16px;font-size:16px;font-weight:normal" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(167,29,93)" class="">class</span> <span style="color:rgb(0,134,179)" class="">Foundation.Date</span></pre></div><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">This means that clients of Foundation that wish to see only <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">Date</code> must know the exact kind of declaration that identifier is. In addition, though this import specifies exactly one class be imported from Foundation, the actual semantics mean Swift will recursively open all of Foundation's submodules so you can see, and use, every other identifier anyway - and they are not filtered from code completion. Qualified imports deserve to be first-class in Swift, and that is what we intend to make them with this proposal.</p></h1><h2 style="margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#proposed-solution" style="color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1;background-color:transparent" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Proposed solution</h2><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class=""><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">The grammar and semantics of qualified imports will change completely with the addition of <em class="">import qualifiers</em> and <em class="">import directives</em>. We also introduce two new contextual keywords: <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">using</code> and <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">hiding</code>, to facilitate fine-grained usage of module contents.</p></h1><h2 style="margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#detailed-design" style="color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1;background-color:transparent" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Detailed design</h2><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class=""><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">Qualified import syntax will be revised to the following</p><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:16px;font-weight:normal;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgb(247,247,247)" class=""><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;padding:0px;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent" class="">import-decl -> import <import-path> <(opt) import-directive-list>
import-path -> <identifier>
-> <identifier>.<identifier>
import-directive-list -> <import-directive>
-> <import-directive> <import-directive-list>
import-directive -> using (<identifier>, ...)
-> hiding (<identifier>, ...)
</code></pre><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">This introduces the concept of an import <em class="">directive</em>. An import directive is a file-local modification of an imported identifier. A directive can be one of 2 operations:</p><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">1) <em class="">using</em>: The <em class="">using</em> directive is followed by a list of identifiers for non-member nominal declarations within the imported module that should be exposed to this file. </p><div style="margin-bottom:16px;font-size:16px;font-weight:normal" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgb(247,247,247)" class=""><span style="color:rgb(150,152,150)" class="">// The only visible parts of Foundation in this file are </span>
<span style="color:rgb(150,152,150)" class="">// Foundation.Date, Foundation.DateFormatter, and Foundation.DateComponents</span>
<span style="color:rgb(150,152,150)" class="">//</span>
<span style="color:rgb(150,152,150)" class="">// Previously, this was</span>
<span style="color:rgb(150,152,150)" class="">// import class Foundation.Date</span>
<span style="color:rgb(150,152,150)" class="">// import class Foundation.DateFormatter</span>
<span style="color:rgb(150,152,150)" class="">// import class Foundation.DateComponents</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Foundation</span> using (Date, DateFormatter, DateComponents)</pre></div><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">2) <em class="">hiding</em>: The <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">hiding</code> directive is followed by a list of identifiers for non-member nominal declarations within the imported module that should be hidden from this file.</p><div style="margin-bottom:16px;font-size:16px;font-weight:normal" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgb(247,247,247)" class=""><span style="color:rgb(150,152,150)" class="">// Imports all of Foundation except `Date`</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Foundation</span> hiding (Date)</pre></div><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">As today, all hidden identifiers do not hide the type, they merely hide that type’s members and its declaration. For example, this means values of hidden types are still allowed. Unlike the existing implementation, using their members is forbidden.</p><div style="margin-bottom:16px;font-size:16px;font-weight:normal" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgb(247,247,247)" class=""><span style="color:rgb(150,152,150)" class="">// Imports `DateFormatter` but the declaration of `Date` is hidden.</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Foundation</span> using (DateFormatter)
<span style="color:rgb(167,29,93)" class="">var</span> d <span style="color:rgb(167,29,93)" class="">=</span> DateFormatter()<span style="color:rgb(167,29,93)" class="">.</span>date(from: <span style="color:rgb(24,54,145)" class=""><span class="">"</span>...<span class="">"</span></span>) <span style="color:rgb(150,152,150)" class="">// Valid</span>
<span style="color:rgb(167,29,93)" class="">var</span> dt <span style="color:rgb(167,29,93)" class="">:</span> Date <span style="color:rgb(167,29,93)" class="">=</span> DateFormatter()<span style="color:rgb(167,29,93)" class="">.</span>date(from: <span style="color:rgb(24,54,145)" class=""><span class="">"</span>...<span class="">"</span></span>) <span style="color:rgb(150,152,150)" class="">// Invalid: Cannot use name of hidden type.</span>
d<span style="color:rgb(167,29,93)" class="">.</span>addTimeInterval(<span style="color:rgb(0,134,179)" class="">5</span><span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(0,134,179)" class="">0</span>) <span style="color:rgb(150,152,150)" class="">// Invalid: Cannot use members of hidden type.</span></pre></div><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">Import directives chain to one another and can be used to create a fine-grained module import:</p><div style="margin-bottom:16px;font-size:16px;font-weight:normal" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgb(247,247,247)" class=""><span style="color:rgb(150,152,150)" class="">// This imports Swift.Int, Swift.Double, and Swift.String but hides Swift.String.UTF8View</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Swift</span> using (<span style="color:rgb(0,134,179)" class="">String</span>, <span style="color:rgb(0,134,179)" class="">Int</span>, <span style="color:rgb(0,134,179)" class="">Double</span>)
hiding (<span style="color:rgb(0,134,179)" class="">String</span><span style="color:rgb(167,29,93)" class="">.</span>UTF8View)</pre></div><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">Directive chaining occurs left-to-right:</p><div style="margin-bottom:16px;font-size:16px;font-weight:normal" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgb(247,247,247)" class=""><span style="color:rgb(150,152,150)" class="">// This says to 1) Use Int 2) Hide String 3) rename Double to Triple. It is invalid</span>
<span style="color:rgb(150,152,150)" class="">// because 1) Int is available 2) String is not, error.</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Swift</span> using (<span style="color:rgb(0,134,179)" class="">Int</span>) hiding (<span style="color:rgb(0,134,179)" class="">String</span>)
<span style="color:rgb(150,152,150)" class="">// Valid. This will be merged as `using (Int)`</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Swift</span> using () using (<span style="color:rgb(0,134,179)" class="">Int</span>)
<span style="color:rgb(150,152,150)" class="">// Valid. This will be merged as `hiding (String, Double)`</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Swift</span> hiding (<span style="color:rgb(0,134,179)" class="">String</span>) hiding (<span style="color:rgb(0,134,179)" class="">Double</span>) hiding ()
<span style="color:rgb(150,152,150)" class="">// Valid (if redundant). This will be merged as `using ()`</span>
<span style="color:rgb(167,29,93)" class="">import</span> <span style="color:rgb(0,134,179)" class="">Swift</span> using (<span style="color:rgb(0,134,179)" class="">String</span>) hiding (<span style="color:rgb(0,134,179)" class="">String</span>)</pre></div><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">Because import directives are file-local, they will never be exported along with the module that declares them.</p></h1><h2 style="margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#impact-on-existing-code" style="color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1;background-color:transparent" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Impact on existing code</h2><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class=""><p style="margin-top:0px;margin-bottom:16px;font-size:16px;font-weight:normal" class="">Existing code that is using qualified module import syntax (<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">import {func|class|typealias|class|struct|enum|protocol} <qualified-name></code>) will be deprecated and should be removed or migrated. </p></h1><h2 style="margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#alternatives-considered" style="color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1;background-color:transparent" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Alternatives considered</h2><h1 style="margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class=""><div style="margin-top:0px;font-size:16px;font-weight:normal;margin-bottom:0px!important" class="">A previous iteration of this proposal introduced an operation to allow the renaming of identifiers, especially members. The original intent was to allow file-local modifications of APIs consumers felt needed to conform to their specific coding style. On review, we felt the feature was not as significant as to warrant inclusion and was ripe for abuse in large projects.</div></h1></div></div><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""><br class=""></blockquote></div><br class=""></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></blockquote></div></div></blockquote></div></div></blockquote></div><br class=""></div></div></blockquote></div></blockquote></div></div></blockquote></div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></blockquote></div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div></div></blockquote></div></div></div><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div><br class=""></div></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>