“The Phase Distinction” is a semantic one, not one built into the import system 
itself.  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.  Ne’er the twain shall meet.  A qualified import is defining a procedure 
to import a subset of identifiers.  That’s it.

> On Jul 20, 2016, at 4:17 PM, Xiaodi Wu <[email protected]> wrote:
> 
> On Wed, Jul 20, 2016 at 4:57 PM, Robert Widmann <[email protected] 
> <mailto:[email protected]>> wrote:
> 
>> On Jul 20, 2016, at 2:52 PM, Robert Widmann via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>>> 
>>> On Jul 20, 2016, at 2:35 PM, Xiaodi Wu <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> 
>>> 
>>> On Wed, Jul 20, 2016 at 4:24 PM, Robert Widmann <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>>> On Jul 20, 2016, at 2:19 PM, Xiaodi Wu <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> On Wed, Jul 20, 2016 at 4:06 PM, Robert Widmann <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>>> On Jul 20, 2016, at 2:04 PM, Robert Widmann via swift-evolution 
>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>> 
>>>>>> 
>>>>>> On Jul 20, 2016, at 1:59 PM, Xiaodi Wu <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> 
>>>>>> Why is hiding in-scope but renaming out-of-scope?
>>>>> 
>>>>> 
>>>>> Because hiding and renaming can be used in combination to subset out 
>>>>> APIs, not alter them.
>>>>> 
>>>> 
>>>> I mistyped.  Should be "Because hiding and using can be used in 
>>>> combination to subset out APIs, not alter them."
>>>> 
>>>> 
>>>> Sure, I buy that.
>>>> 
>>>>>> Both are additive to Swift, 
>>>>> 
>>>>> As part of this proposal, both are source-breaking.
>>>> 
>>>> 
>>>> 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?
>>> 
>>> 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.
>>> 
>>> 
>>> 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.
>>> 
>>> 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?
>>> 
>> 
>> 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 
>> 
>> import Swift hiding (String)
>> 
>> doesn’t translate into
>> 
>> import Swift renaming (String, to: _)
>> 
>> it translates into
>> 
>> import Swift hiding () renaming (String, to: _)
>> 
>> 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 
>> 
>> open A hiding (xs) renaming (ys to zs)
>> 
>> to mean
>> 
>> open A using (A; xs; ys) renaming (ys to zs)
>> 
> 
> 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.
> 
> 
> This is very illuminating. I think I've rather misunderstood what it is 
> you're proposing. I wonder if others did also.
> 
> 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").
> 
> 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?
> 
> 
> 
>>> 
>>> 
>>>> 
>>>>>> and as has been argued by others, the former is a special case of the 
>>>>>> latter.
>>>>> 
>>>>> 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. 
>>>> 
>>>> 
>>>> 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.
>>>>  
>>> 
>>> 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.
>>> 
>>> 
>>> Right. See above about my argument as to which parts of your proposal have 
>>> to be source-breaking, and which don't.
>>>  
>>> 
>>> 
>>>>> 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).
>>>> 
>>>> 
>>>> 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.
>>> 
>>> 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.
>>> 
>>> 
>>> This is, I think, a spurious argument. I can equally have 500 lines of 
>>> private typealiased crap that has to be copypasta'd.
>>>  
>>> 
>>> 
>>>>  
>>>>>> On Wed, Jul 20, 2016 at 15:55 Brandon Knope <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> I meant is there any reason for requiring parentheses 
>>>>>> 
>>>>>> On Jul 20, 2016, at 4:53 PM, Robert Widmann <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> 
>>>>>>> Renaming is out of scope for this proposal, that’s why.
>>>>>>> 
>>>>>>>> On Jul 20, 2016, at 1:26 PM, Brandon Knope <[email protected] 
>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>> 
>>>>>>>> I prefer this 100x more
>>>>>>>> 
>>>>>>>> Is there any reason why this wouldn't work?
>>>>>>>> 
>>>>>>>> Brandon 
>>>>>>>> 
>>>>>>>> On Jul 20, 2016, at 4:13 PM, Xiaodi Wu <[email protected] 
>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>> 
>>>>>>>>> Yeah, I'd be happy to lose the parentheses as well.
>>>>>>>>> 
>>>>>>>>> In the last thread, my take on simplifying the proposed syntax was:
>>>>>>>>> 
>>>>>>>>> ```
>>>>>>>>> import Swift using String, Int
>>>>>>>>> 
>>>>>>>>> // or, for hiding:
>>>>>>>>> import Swift using Int as _
>>>>>>>>> ```
>>>>>>>>> 
>>>>>>>>> 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.
>>>>>>>>> On Wed, Jul 20, 2016 at 15:01 Brandon Knope <[email protected] 
>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> On Jul 20, 2016, at 3:08 PM, Xiaodi Wu via swift-evolution 
>>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>>> 
>>>>>>>>>> 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:
>>>>>>>>>> 
>>>>>>>>>> ```
>>>>>>>>>> import Swift using (String, Int)
>>>>>>>>>> // imports only String and Int
>>>>>>>>>> import Swift using (String, Int) hiding (String)
>>>>>>>>>> // imports only Int
>>>>>>>>>> import Swift hiding (String, Int)
>>>>>>>>>> // imports everything except String and Int
>>>>>>>>>> import Swift hiding (String, Int) using (String)
>>>>>>>>>> // imports *nothing*? nothing except String? everything except Int? 
>>>>>>>>>> confusing.
>>>>>>>>>> ```
>>>>>>>>>> 
>>>>>>>>>> By contrast, Joe's proposed syntax (with some riffs) produces 
>>>>>>>>>> something much more terse *and* much more clear:
>>>>>>>>>> 
>>>>>>>>>> ```
>>>>>>>>>> import Swift.*
>>>>>>>>>> import Swift.(Int as MyInt, *)
>>>>>>>>>> import Swift.(Int as _, *)
>>>>>>>>>> ```
>>>>>>>>> 
>>>>>>>>> I really don't find this much clearer than the proposed one. The 
>>>>>>>>> proposal reads much clearer. 
>>>>>>>>> 
>>>>>>>>> Joe's syntax has a lot going on in my opinion.
>>>>>>>>> 
>>>>>>>>> For the proposal, do we really need the parentheses? It makes the 
>>>>>>>>> syntax look heavier
>>>>>>>>> 
>>>>>>>>> Brandon 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> On Wed, Jul 20, 2016 at 1:52 PM, Robert Widmann via swift-evolution 
>>>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>>>> Hello all,
>>>>>>>>>> 
>>>>>>>>>> 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.
>>>>>>>>>> 
>>>>>>>>>> It can be had inline with this email, on Github 
>>>>>>>>>> <https://github.com/apple/swift-evolution/pull/440>, or as a gist 
>>>>>>>>>> <https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6>.
>>>>>>>>>> 
>>>>>>>>>> Thanks,
>>>>>>>>>> 
>>>>>>>>>> ~Robert Widmann
>>>>>>>>>> 
>>>>>>>>>> Qualified Imports Revisited
>>>>>>>>>> 
>>>>>>>>>> Proposal: SE-NNNN 
>>>>>>>>>> <https://gist.github.com/CodaFi/NNNN-first-class-qualified-imports.md>
>>>>>>>>>> Authors: Robert Widmann <https://github.com/codafi>, TJ Usiyan 
>>>>>>>>>> <https://github.com/griotspeak>
>>>>>>>>>> Status: Awaiting review
>>>>>>>>>> Review manager: TBD
>>>>>>>>>> 
>>>>>>>>>>  
>>>>>>>>>> <https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#introduction>Introduction
>>>>>>>>>> 
>>>>>>>>>> We propose a complete overhaul of the qualified imports syntax and 
>>>>>>>>>> semantics.
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  
>>>>>>>>>> <https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#motivation>Motivation
>>>>>>>>>> 
>>>>>>>>>> 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
>>>>>>>>>> 
>>>>>>>>>> import class Foundation.Date
>>>>>>>>>> This means that clients of Foundation that wish to see only Date 
>>>>>>>>>> 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.
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  
>>>>>>>>>> <https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#proposed-solution>Proposed
>>>>>>>>>>  solution
>>>>>>>>>> 
>>>>>>>>>> The grammar and semantics of qualified imports will change 
>>>>>>>>>> completely with the addition of import qualifiers and import 
>>>>>>>>>> directives. We also introduce two new contextual keywords: using and 
>>>>>>>>>> hiding, to facilitate fine-grained usage of module contents.
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  
>>>>>>>>>> <https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#detailed-design>Detailed
>>>>>>>>>>  design
>>>>>>>>>> 
>>>>>>>>>> Qualified import syntax will be revised to the following
>>>>>>>>>> 
>>>>>>>>>> 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>, ...)
>>>>>>>>>> This introduces the concept of an import directive. An import 
>>>>>>>>>> directive is a file-local modification of an imported identifier. A 
>>>>>>>>>> directive can be one of 2 operations:
>>>>>>>>>> 
>>>>>>>>>> 1) using: The using directive is followed by a list of identifiers 
>>>>>>>>>> for non-member nominal declarations within the imported module that 
>>>>>>>>>> should be exposed to this file. 
>>>>>>>>>> 
>>>>>>>>>> // The only visible parts of Foundation in this file are 
>>>>>>>>>> // Foundation.Date, Foundation.DateFormatter, and 
>>>>>>>>>> Foundation.DateComponents
>>>>>>>>>> //
>>>>>>>>>> // Previously, this was
>>>>>>>>>> // import class Foundation.Date
>>>>>>>>>> // import class Foundation.DateFormatter
>>>>>>>>>> // import class Foundation.DateComponents
>>>>>>>>>> import Foundation using (Date, DateFormatter, DateComponents)
>>>>>>>>>> 2) hiding: The hiding directive is followed by a list of identifiers 
>>>>>>>>>> for non-member nominal declarations within the imported module that 
>>>>>>>>>> should be hidden from this file.
>>>>>>>>>> 
>>>>>>>>>> // Imports all of Foundation except `Date`
>>>>>>>>>> import Foundation hiding (Date)
>>>>>>>>>> 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.
>>>>>>>>>> 
>>>>>>>>>> // Imports `DateFormatter` but the declaration of `Date` is hidden.
>>>>>>>>>> import Foundation using (DateFormatter)
>>>>>>>>>> 
>>>>>>>>>> var d = DateFormatter().date(from: "...") // Valid
>>>>>>>>>> var dt : Date = DateFormatter().date(from: "...") // Invalid: Cannot 
>>>>>>>>>> use name of hidden type.
>>>>>>>>>> d.addTimeInterval(5.0) // Invalid: Cannot use members of hidden type.
>>>>>>>>>> Import directives chain to one another and can be used to create a 
>>>>>>>>>> fine-grained module import:
>>>>>>>>>> 
>>>>>>>>>> // This imports Swift.Int, Swift.Double, and Swift.String but hides 
>>>>>>>>>> Swift.String.UTF8View
>>>>>>>>>> import Swift using (String, Int, Double) 
>>>>>>>>>>              hiding (String.UTF8View)
>>>>>>>>>> Directive chaining occurs left-to-right:
>>>>>>>>>> 
>>>>>>>>>> // This says to 1) Use Int 2) Hide String 3) rename Double to 
>>>>>>>>>> Triple.  It is invalid
>>>>>>>>>> // because 1) Int is available 2) String is not, error.
>>>>>>>>>> import Swift using (Int) hiding (String)
>>>>>>>>>> // Valid.  This will be merged as `using (Int)`
>>>>>>>>>> import Swift using () using (Int)
>>>>>>>>>> // Valid.  This will be merged as `hiding (String, Double)`
>>>>>>>>>> import Swift hiding (String) hiding (Double) hiding ()
>>>>>>>>>> // Valid (if redundant). This will be merged as `using ()`
>>>>>>>>>> import Swift using (String) hiding (String)
>>>>>>>>>> Because import directives are file-local, they will never be 
>>>>>>>>>> exported along with the module that declares them.
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  
>>>>>>>>>> <https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#impact-on-existing-code>Impact
>>>>>>>>>>  on existing code
>>>>>>>>>> 
>>>>>>>>>> Existing code that is using qualified module import syntax (import 
>>>>>>>>>> {func|class|typealias|class|struct|enum|protocol} <qualified-name>) 
>>>>>>>>>> will be deprecated and should be removed or migrated. 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>  
>>>>>>>>>> <https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6#alternatives-considered>Alternatives
>>>>>>>>>>  considered
>>>>>>>>>> 
>>>>>>>>>> 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.
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> _______________________________________________
>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> _______________________________________________
>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to