~Robert Widmann

2016/07/21 3:19、Pyry Jahkola via swift-evolution <[email protected]> 
のメッセージ:

> I think we're getting somewhere.
> 
>>> On 21 Jul 2016, at 12:01, Robert Widmann <[email protected]> wrote:
>> 
>>>> (An excerpt about the hiding directive)
>>> 
>>> 4. Hmm, the above design detail is easily missed when reading the proposal. 
>>> So what you're proposing is that the hiding of Date essentially turns Date 
>>> into a type that the code will know almost nothing about, except it's 
>>> something we can pass to other types' methods that expect a Date, am I 
>>> right?
>>> 
>>> What's the benefit in that? Do you anticipate it will make importing 
>>> lighter somehow, possibly improving compilation or library loading speed? 
>>> You mentioned something along those lines in the Motivation, but I'm not 
>>> sure if I got it right here.
>> 
>> It is so that use of an API in a framework like Foundation does not 
>> necessitate polluting your Swift files with a million using imports - thus 
>> defeating the purpose of this proposal.
> 
> You explained further below what else `hiding` imports can be used for. But 
> my comment was motivated by your example of `import Foundation hiding 
> (Date)`. 
> 
> I fail to see how the lack of `hiding` imports would imply Swift files with a 
> lot using imports. In my counting, they amount to at most one extra using 
> import. (And I propose ~10 lines below what would get that to zero.)
> 
> The simple reason I could see someone write `import Foundation hiding (Date)` 
> is because another imported module "Julian" she uses happens to export 
> another Date type which she wants to use instead. And if we could just as 
> well solve that use case by making it so that
> 
>     import Foundation
>     import Julian, Julian using (Date)
>     assert(Date.self == Julian.Date.self)
> 
> brings in both modules but makes Julian.Date the one that Date is shorthand 
> of.
> 
> Besides, Joe and friends offered the use of `*` to mean "and everything 
> else", which is problematic because `*` also happens to be an operator 
> function name. But we could make it so that the underscore imports everything 
> else (without explicit qualification), making the above example exactly 
> equivalent to:
> 
>     import Foundation using (_)   // same as `import Foundation`
>     import Julian using (_, Date) // bring in Date explicitly and all else 
> implicitly
>     assert(Date.self == Julian.Date.self)

Funny, others have been suggesting _ be used as a special namespace to hide 
identifiers in.  It implies you don't care about identifiers, not that you want 
all of them.

> 
> 
>> DateFormatter alone needs to know about Date, String, TimeInterval, 
>> Calendar, Locale, and TimeZone.  Each of those needs to know about 
>> additional components.  To require an import decl to use these types 
>> explicitly would be madness.  You'd just wind up importing Foundation anyway.
> 
> "You'd just wind up importing Foundation anyway" is an argument that doesn't 
> seem imply from the given Motivation section AFAICT.

I should be more clear: If we requires you to qualified import types without 
these allowances then you would have to recursively import types out of 
Foundation until you wind up importing the whole thing anyway.  To be able to 
use DateFormatter you shouldn't have to tell Swift you also want to use Date, 
String, TimeInterval, etc.  We know you want to, we can see all of these 
identifiers.  When the time comes for you to pick a member on Date, then you 
want a using or hiding import to let us know you want to see it.

> 
> I can see three kinds of problems here (objective or subjective), caused by 
> importing the whole Foundation:
> Identifier name conflicts, which we could solve with just the `import Module 
> using (name, Name, _)` syntax, essentially indicating which Module should be 
> preferred.
The grammar makes no allowances for types to be imported there, only qualified 
module name.  Not sure what you mean.
> 
> Identifier names shadowing module names, where e.g. a `private enum 
> Foundation {}` disables the fully qualified access to the Foundation module's 
> API). This remains an unsolved problem, but the introduction of qualified 
> module imports `import Foundation as Foundation` or `import Foundation as F` 
> (or, heh, `import Foundation as is`) would be one way of going about it.

And additive and can be introduced in a future proposal as a new directive on 
top of this system.  We wanted this, the community had reservations, we backed 
off.
> 
> Auto-completer "hygiene", or being explicit which part of a large imported 
> API is not considered appropriate to use by the author
> Point 3 is the only problem that `hiding` imports could be uniquely used for, 
> especially if they can be narrowed down to members of imported types and 
> extensions (e.g. Swift.String.UTF8View, as given in the proposal). But is 
> that worth having?

We need to be able to disambiguate more than just top-level names, for one.  
Hiding can do that.

> 
> 
>>> 5. These chaining rules do fit on the back of a napkin, but I'm not sure if 
>>> we need them at all. I'm not convinced we need `hiding` imports, and 
>>> without hiding imports, we need no rules for the order of imports.
>> 
>> How else are we to allow you to import a using type but not any of its 
>> member types?
> 
> I don't know. I'm asking "why?" not "how?"

That is why, just rhetorical.

> 
> 
>> How could we support removing APIs related to NSCell in AppKit apps? How 
>> about NSStream everywhere else? How else can we allow, in the future, the 
>> ability to import NSObject but none of its KVO-related members?
> 
> I'm saying you should explain this in the Motivation. Or consider moving the 
> `hiding` import syntax into a further proposal.

Fair.

> 
> 
>> A hiding import is an invariant: It says a particular API should never be 
>> considered for use in this file.  The very act of 'using' an identifier 
>> means you are hiding all others.  The very act of 'hiding' an identifier 
>> means you are using all others.
> 
> That is very logical. But it would be better if there was a real-world 
> example use case given where the use of `hiding` was a clear win over a 
> combination of `import` and `import ... using (...)`. The current one about 
> Date isn't very convincing because instead of hiding one, it could be solved 
> by highlighting (using) the other.

I have given one.  Show me how to express the "give me String but not 
String.UTF8View" example without hiding?

> 
> 
>>> What I will keep suggesting is that `using` imports actually take up the 
>>> name in the file-local scope such that nothing else in the same file's 
>>> scope — be it another `import ... using (...)`, a local type declaration, 
>>> function, or value — can declare the same name with a different meaning. 
>>> That way, a plain
>>> 
>>>     import Foo
>>> 
>>> can import everything from Foo, while another
>>> 
>>>     import Foo using (Bar)
>>> 
>>> can be used to explicitly choose the Bar the code is about to use.
>> 
>> That was the plan.  You will receive an "invalid redeclaration" error as 
>> always. 
> 
> 👍!
> 
> — Pyry
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> 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