[swift-evolution] Enhanced existential types proposal discussion

L Mihalkovic laurent.mihalkovic at gmail.com
Fri Jun 17 16:16:16 CDT 2016


added a few comments to https://gist.github.com/lmihalkovic/68c321ea7ffe27e553e37b794309b051 to clarify the rational. it is by no mean the only way or a good way, but IMO there are far worse ways to do the same.


> On Jun 6, 2016, at 1:20 AM, Douglas Gregor via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On May 18, 2016, at 12:35 AM, Austin Zheng <austinzheng at gmail.com <mailto:austinzheng at gmail.com>> wrote:
>> 
>> I've put together a considerably more detailed draft proposal, taking into account as much of Matthew's feedback as I could. You can find it below:
>> 
>> https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/XXXX-enhanced-existentials.md <https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/XXXX-enhanced-existentials.md>
>> 
>> Since there is no chance this will come up for review anytime soon, I expect to make significant revisions to it over the next month or so. Any feedback would be greatly appreciated.
> 
> This is very much Swift 4 territory, but I can’t help myself… so…
> 
> The actual feature description is spread out through this very long document, with user-facing ideas (e.g., using “anonymous associated types”) intermixed with deeper technical details (existential type equivalence), so it’s very daunting to read. Please bring the user-facing features to the front (“Proposed Solution”) with examples, and save the deeper technical details for “Detailed Design”. You want more readers to make it through the part that affects them.
> 
> Shortcut 'dot' notation: If there is only one protocol with associated types specified in the requirements, and there are no nested Any<...> requirements with where clauses of their own, that protocol's name can be omitted from the whereclause constraints:
> 
> // Okay
> // Would otherwise be Any< ~ where Collection.Element == Int>
> let a : Any<class, Collection, Any<Streamable, CustomStringConvertible> where .Element == Int>
> 
> // NOT ALLOWED
> // Both Collection and OptionSetType have associated types.
> let b : Any<Collection, OptionSetType where .Element == Int>
> FWIW, I think “.Element == Int” should be the only syntax. In generic signatures, if you have two different protocols with same-named associated types, and a given type parameter (or associated type) conforms to both protocols, the associated types are (implicitly) made equivalent via an inferred same-type constraint. So there’s no reason to introduce the “Collection.Element == Int” syntax, because the “Collection” part is basically irrelevant.
> 
> Once existentials have been suitably enhanced, there is a strong analogy between an existential and a generic signature with a single type parameter that you can’t name. An existential Any<Collection where .Element : Equatable> has most of the same characteristics as a generic something with the signature <T : Collection where T.Element : Equatable>. Specifically, the sections on “Existential type equivalence”, “Ordering”, “Real types to anonymous associated types”, “Anonymous associated types to real types”. could be reduced to a few small, simple examples and a mention of the analogous behavior of generics. It will be far easier to explain this way, and readers don’t need to get immersed in the details. Where there are differences vs. generics, that’s important to point out.
> 
> “Associated typealias rewriting”: this also falls out of the equivalence with generics + SE-0092.
> 
> “Associated types and member exposure”: you don’t make the point that it only makes sense to refer to the associated types of a let constant; a var could change its type dynamically, which would invalidate the typing rules. Did you consider just using “x.dynamicType” in the type grammar for this? It’s more general, in that you can refer to associated types but also talk about the dynamic type of “x” itself, e.g.,
> 
> 	let x: Equatable = …
> 	let y: Equatable = …
> 	if let yAsX = y as? x.dynamicType { … x == yAsX … }
> 
> which is (almost?) as powerful as a general “open” expression.
> 
> I’m not a fan of the “anonymous associated types” terminology: these are associated types of a type of some runtime-defined value. The only thing “anonymous” about them is that it’s harder to spell the base type; otherwise, they’re just like associated types of a generic type parameter. Again, the generics analogy is strong here.
> 
> FWIW, I don’t think we’ll ever need “opening existentials” with what you’ve described here. Also, remember that a method of a protocol extension essentially opens “Self”, so we already have one way to open an existential (and that’s probably enough).
> 
> I was a little surprised you didn’t point out that AnyObject could become
> 
> 	typealias AnyObject = Any<class>
> 
> or give the nice “AnyCollection” syntax:
> 
> 	typealias AnyCollection<T> = Any<Collection where .Element == T>
> 
> the latter of which is fairly important, because it gives nice syntactic sure to one of the most highly-requested features [*]. I’d suggest having that example very, very early.
> 
> 	- Doug
> 
> [*] That generally comes in as “Swift should have parameterized protocols…”
> 


@doug : watched and very much appreciated your presentation on what makes a good API… reminded me of a job interview with Bertand Serlet a few years ago.. you guys have managed to remain very consistent over a very long period of time, and it looks like Swift is following in the foot-steps.  
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160617/12f6968f/attachment.html>


More information about the swift-evolution mailing list