> Am 27.05.2016 um 17:33 schrieb Matthew Johnson <[email protected]>:
>
>>
>> On May 27, 2016, at 3:45 AM, Austin Zheng via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>> As far as I understand it (and the core team as well, judging from their
>> posts), an existential is just a type defined by an interface of some sort
>> ("there exists a type that is capable of X, Y, and Z"), and you can put any
>> value of a type that meets that interface in the existential. The associated
>> types/self types requirements are non-essential add-ons.
>>
>> I am about to fall asleep, though, so I'd be happy to reread the article
>> tomorrow and if I'm wrong, make the change.
>
> This is my understanding as well. The way I understand existential is that
> it means “there exists a type such that you can perform a given set of
> operations on it”. Whether the operations are defined in terms of associated
> types or not is irrelevant under this meaning.
Hmm, that sounds more like structural subtyping which is quite different.
`any<P>` means a type conforming to P (nominal subtyping!) not a type
conforming to the set of operations P happens to contain (structural subtyping).
If P has no associated types (or self type requirements) this is just normal
nominal subtyping without any wrinkles (and `any<P>` is equal to `P`).
But if P does have associated types then all types are conforming which are
(still nominally) conforming to P but without any restrictions placed on the
associated type (or with those restrictions given in the optional constraint
clause).
protocol P {
associatedtype T
var a: T
func f(_ value: T) -> Int
}
struct A : P {
var a: Int
func f(_ value: Int) -> Int { return value }
}
struct B : P {
var a: String
func f(_ value: String) -> Int { return value.characters.count }
}
I can have a collection of `any<P>` with values having different concrete types
for T!
Example:
let a = A()
let b = B()
let ps: [any<P>]
ps.append(a)
ps.append(b)
This is absolutely fine, because the unbound associated type cannot escape,
i.e. the type of a.a would be a.T and therefore only be available in the scope
of a.
That is very different to generics where I would have to bind the type
parameter to a fixed value:
class C<T> {
var a: T
func f(_ value: T) -> Int { return 0 } // dummy implementation because
Swift has no abstract classes
}
class C1 : C<Int> {
var a: Int
func f(_ value: Int) -> Int { return value }
}
class C2 : C<String> {
var a: String
func f(_ value: String) -> Int { return value.characters.count }
}
let c1 = C1()
let c2 = C2()
let cs: [C<Int>] // note: have to supply a concrete value for T
cs.append(c1)
// cs.append(c2) // not possible because T had to be bound
That distinction is what makes existentials special. And therefore that is the
way I understand existentials: types having unbound type parameters.
Haskell: https://wiki.haskell.org/Existential_type
Wikipedia: https://en.wikipedia.org/wiki/Type_system#Existential_types
Scala: http://www.drmaciver.com/2008/03/existential-types-in-scala/ or
http://typelevel.org/blog/2015/02/26/rawtypes.html
I haven’t found other definitions for existential types. They all hinge around
unbound type parameters.
Hope I didn’t ramble too much...
-Thorsten
>
>>
>> Austin
>>
>>> On May 27, 2016, at 1:42 AM, Thorsten Seitz <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>
>>>> Am 27.05.2016 um 10:30 schrieb Austin Zheng <[email protected]
>>>> <mailto:[email protected]>>:
>>>>
>>>> Thank you for all your great feedback!
>>>>
>>>> Let me try rephrasing what I said, because it wasn't very clear. Apologies.
>>>>
>>>> NSView is not an existential, like you said.
>>>>
>>>> Any<...> syntax is, as far as we've seen, always used for existential
>>>> types.
>>>>
>>>> "Any<NSView>" *looks* like an existential because it has the "Any<...>"
>>>> syntax, but if it's a synonym for just "NSView" then it actually isn't an
>>>> existential.
>>>>
>>>> So "Any<NSView>" isn't an existential, but it looks like one. This is
>>>> something I think would be confusing to a lot of people, and also
>>>> redundant: there is no reason as far as I know to ever write
>>>> Any<SomeClass> when you could just write SomeClass, so by banning the
>>>> confusing form we don't lose any expressive power.
>>>
>>> Ah, ok! So `Any<NSView>` is just the same as `NSView`. That’s my
>>> understanding as well :-)
>>>
>>> But this does not apply only to classes: `Any<CustomStringConvertible>` is
>>> just the same as `CustomStringConvertible`, too, because
>>> `CustomStringConvertible` does not have associated types or self type
>>> requirements (it is *not* an existential in Wikipedia’s sense).
>>>
>>> Banning `Any<Foo>` where `Foo` does not have associated types or self type
>>> requirements would be the right thing to do, I think, regardless whether
>>> `Foo` is a class or a protocol. This would make it clear that `Any<Foo>` is
>>> a *real* existential.
>>>
>>> -Thorsten
>>>
>>>
>>>>
>>>> Hope that helps,
>>>> Austin
>>>>
>>>>> On May 27, 2016, at 1:24 AM, Thorsten Seitz <[email protected]
>>>>> <mailto:[email protected]>> wrote:
>>>>>
>>>>>>
>>>>>> Am 26.05.2016 um 22:44 schrieb Austin Zheng via swift-evolution
>>>>>> <[email protected] <mailto:[email protected]>>:
>>>>>>
>>>>>> (inline)
>>>>>>
>>>>>> On Thu, May 26, 2016 at 12:22 PM, David Hart <[email protected]
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> Hi Austin,
>>>>>>
>>>>>> I never had te occasion to say thanks for the work you have put in this
>>>>>> proposal, so thanks! I’m really looking forward to be able to have some
>>>>>> form of it accepted and implemented in Swift.
>>>>>>
>>>>>> Thank you! I just hope a proposal like this one ends up being good
>>>>>> enough that it means less work for the core team, not more...
>>>>>>
>>>>>>
>>>>>> Here are a few comments:
>>>>>>
>>>>>> 1) Why would Any<> and Any<NSView> be illegal? What error messages would
>>>>>> they generate? Why not make them simply synonymous to Any, and NSView,
>>>>>> the same way protocol<> currently behaves?
>>>>>>
>>>>>> "Any<>" being illegal is a syntactic battle that is being fought over in
>>>>>> a different thread; I'm not personally invested one way or another. (We
>>>>>> might not even adopt "Any" syntax specifically; Joe Groff has ideas for
>>>>>> a different syntax that doesn't use the brackets.)
>>>>>>
>>>>>> "Any<NSView>" is an existential, and "NSView" isn't. Existentials'
>>>>>> metatypes are different from the metatypes of concrete types, and the
>>>>>> ways they can be used with generics is different as well. My opinion is
>>>>>> that Any<...> signifies an existential, and allowing the use of
>>>>>> "Any<SomeClass>" as a concrete type would just confuse people even more.
>>>>>
>>>>>
>>>>> This is something where I still have a problem understanding what an
>>>>> existential is in the Swift sense. In the "normal“ sense (as defined in
>>>>> Wikipedia or Haskell) NSView cannot be an existential because it has no
>>>>> unbound associated types. It cannot be just made an existential either.
>>>>> How would that work?
>>>>>
>>>>> So, what is the meaning of `Any<NSView>` being an existential? How is
>>>>> that type different from the type `NSView`?
>>>>>
>>>>> -Thorsten
>>>>
>>>
>>
>> _______________________________________________
>> 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