[swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol<P1, P2> syntax with Any<P1, P2>
L Mihalkovic
laurent.mihalkovic at gmail.com
Tue Jun 7 13:35:05 CDT 2016
> On Jun 7, 2016, at 7:51 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
>
>
> on Tue Jun 07 2016, Matthew Johnson <matthew-AT-anandabits.com> wrote:
>
>>> On Jun 6, 2016, at 12:22 AM, Dave Abrahams <dabrahams at apple.com>
>> wrote:
>>>
>>>
>>> on Sun Jun 05 2016, Matthew Johnson <matthew-AT-anandabits.com
>> <http://matthew-at-anandabits.com/>> wrote:
>>>
>>
>>>> Sent from my iPhone
>>>>
>>>>> On Jun 5, 2016, at 3:51 PM, Dave Abrahams via swift-evolution
>>>>> <swift-evolution at swift.org> wrote:
>>>>>
>>>>>
>>>>>> on Wed May 25 2016, Matthew Johnson <swift-evolution at swift.org> wrote:
>>>>>>
>>>>>> Sent from my iPad
>>>>>>
>>>>>>> On May 25, 2016, at 12:10 PM, Jordan Rose via swift-evolution
>>>>>>> <swift-evolution at swift.org> wrote:
>>>>>>>
>>>>>>>
>>>>>>>>> On May 25, 2016, at 05:27, Brent Royal-Gordon via swift-evolution
>>>>>>>>> <swift-evolution at swift.org> wrote:
>>>>>>>>>
>>>>>>>>> AFAIK an existential type is a type T with type parameters that
>>>>>>>>> are still abstract (see for example
>>>>>>>>> https://en.wikipedia.org/wiki/Type_system#Existential_types),
>>>>>>>>> i.e. have not been assigned concrete values.
>>>>>>>>
>>>>>>>> My understanding is that, in Swift, the instance used to store
>>>>>>>> something whose concrete type is unknown (i.e. is still abstract),
>>>>>>>> but which is known to conform to some protocol, is called an
>>>>>>>> "existential". Protocols with associated values cannot be packed
>>>>>>>> into normal existentials because, even though we know that the
>>>>>>>> concrete type conforms to some protocol, the associated types
>>>>>>>> represent additional unknowns, and Swift cannot be sure how to
>>>>>>>> translate uses of those unknown types into callable members. Hence,
>>>>>>>> protocols with associated types are sometimes called
>>>>>>>> "non-existential".
>>>>>>>>
>>>>>>>> If I am misusing the terminology in this area, please understand
>>>>>>>> that that's what I mean when I use that word.
>>>>>>>
>>>>>>> We’re not consistent about it, but an “existential value” is a value
>>>>>>> with protocol or protocol composition type. My mnemonic for this is
>>>>>>> that all we know is that certain operations exist (unlike a generic
>>>>>>> value, where we also have access to the type). John could explain it
>>>>>>> more formally. We sometimes use “existentials” as a (noun) shorthand
>>>>>>> for “existential value”.
>>>>>>>
>>>>>>> In the compiler source, all protocols and protocol compositions are
>>>>>>> referred to as “existential types”, whether they have associated
>>>>>>> types or not. Again, a protocol asserts the existence (and
>>>>>>> semantics) of various operations, but nothing else about the
>>>>>>> conforming type. (Except perhaps that it’s a class.) All protocols
>>>>>>> are thus “existential types” whether or not the language supports
>>>>>>> values having that type.
>>>>>>>
>>>>>>> It is incorrect to say that protocols with associated types (or
>>>>>>> requirements involving Self) are “non-existential”.
>>>>>>
>>>>>> I haven't heard people using this term myself, but I imagine they
>>>>>> probably mean "can't form an existential value with the protocol".
>>>>>> There certainly appears to be a lot of confusion in the community with
>>>>>> many not realizing that this is a temporary limitation of the
>>>>>> implementation, not a necessary fact.
>>>>>
>>>>> As far as I know there is no known way to make protocols with Self
>>>>> requirements usefully “existentiable,” or whatever you want to
>> call it.
>>>>> So unless I'm missing something, in this respect, the limitation
>> is not
>>>>> temporary at all.
>>>>
>>>> Take a look at the Equatable example in the opening existentials
>>>> section of Doug's manifesto:
>>>>
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160229/011666.html
>>>
>>> Yes, note that I said *usefully* “existential.”
>>
>> Fair enough. But note that I was only talking about the inability to
>> form and open such an existential which appears likely to be a
>> temporary limitation given the generics manifesto (of course things
>> could change).
>>
>>> While we can of course downcast in this way, you have to handle the
>>> failure case and it's not like you can use this to make a
>>> heterogeneous Set<Hashable>. AFAICT, this is not at all like what
>>> happens with associated types, where Collection<Element: Int> has
>>> obvious uses.
>>
>> We can’t use this to form Set<Hashable> because existentials don’t
>> conform to the protocol. I know there is complexity in implementing
>> this and it is not possible to synthesize conformance of the
>> existential for all protocols, but AFAIK it isn’t a settled point that
>> we won’t try to improve the situation in some way.
>
> Of course. I'm just trying to point out that such existentials are
> likely to be a whole lot less useful than many people might think.
>
>> Maybe we can make progress here somehow.
>
> Maybe. It's a research project.
>
>> In the meantime, we can make a simple wrapper type to provide the
>> required conformance and make a Set<HashableWrapper> that allows us to
>> put Hashable into a Set. This isn’t ideal but it is a lot less
>> boilerplate than is involved in manual type erasure today where you
>> need to define a struct, base class, and wrapper class. I’d say
>> that’s a win even if we’d like to do better in the future.
>>
>> struct HashableWrapper: Hashable {
>> var value: Hashable
>> public var hashValue: Int { return base.hashValue }
>> }
>>
>> public func ==(lhs: HashableWrapper, res: HashableWrapper) -> Bool {
>> if let lhsValue = lhs.value openas T { // T is a the type of
>> lhsValue, a copy of the value stored in lhs
>> if let rhsValue = rhs.value as? T { // is res also a T?
>> // okay: lhsValue and rhsValue are both of type T, which
>> we know is Equatable
>> if lhsValue == rhsValue {
>> return true
>> }
>> }
>> }
>> return false
>> }
>>
>> (We could also do this with a generic Wrapper<T> and conditional
>> conformance in an `extension Wrapper: Hashable where T == Hashable` if
>> we don’t want a bunch of wrapper types laying around)
>
> I don't think I"ve made my point very well. Equatable (the
> Self-requirement part of Hashable) has a simple answer when the types
> don't match, as I noted in the POP talk. Let me put it differently:
> existentializing a protocol with Self requirements comes with
> limitations that I'm betting most people haven't recognized. For
> example, you won't be able to add two arbitrary FloatingPoint
> existentials. I think many people view working with existentials as
> “easier” or “cleaner” than working with generics, but haven't realized
> that if you step around the type relationships encoded in Self
> requirements and associated types you end up with types that appear to
> interoperate but in fact trap at runtime unless used in exactly the
> right way.
I was thinking more about that, and it seems that of all the possible generics extensions, the least ‘generic’ might be the most interesting in the short term: a type safe way to open existentials
But rather than Doug, strawman suggestion:
if let storedInE1 = e1 openas T { // T is a the type of storedInE1, a copy of the value stored in e1
if let storedInE2 = e2 as? T { // is e2 also a T?
if storedInE1 == storedInE2 { … } // okay: storedInT1 and storedInE2 are both of type T, which we know is Equatable
}
}
I’d rather have something like this (using the new extended ‘if/where’)
if let storedInE1 = e1 as? T;
let storedInE2 = e2 as? T;
storedInE1 == storedInE2 { … } // okay: storedInT1 and storedInE2 are both of type T, which we know is Equatable
}
}
which with my ongoing little pet-project might go down to
if let! e1 as? T;
let! e2 as? T;
e1 == e2 { … } // okay: e1 and e2 are both of type T, which we know is Equatable
}
}
>
> --
> Dave
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160607/c1da95de/attachment.html>
More information about the swift-evolution
mailing list