> On Jul 20, 2016, at 2:52 PM, Robert Widmann via swift-evolution > <[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. >> >> >>> >>>>> 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
