[swift-evolution] Subclass Existentials

David Hart david at hartbit.com
Sun Feb 5 17:20:47 CST 2017


As they are heavily linked, should a change like this be included in the superclass + class proposal or separately?

I'm heavily tending towards (1), and redefining:

typealias Any = Any<>
typealias AnyObject = Any<class>

Does that sound reasonable to you? Just checking before I rewrite this proposal sometime in the next couple of days.

David

> On 3 Feb 2017, at 18:12, Douglas Gregor <dgregor at apple.com> wrote:
> 
> 
>>> On Feb 2, 2017, at 3:24 PM, David Hart <david at hartbit.com> wrote:
>>> 
>>> 
>>>> On 3 Feb 2017, at 00:04, Douglas Gregor via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> 
>>>>> On Feb 2, 2017, at 2:54 PM, David Smith <david_smith at apple.com> wrote:
>>>>> 
>>>>> 
>>>>>> On Feb 2, 2017, at 11:20 AM, Douglas Gregor via swift-evolution <swift-evolution at swift.org> wrote:
>>>>>> 
>>>>>> 
>>>>>> On Feb 1, 2017, at 11:44 PM, Adrian Zubarev <adrian.zubarev at devandartist.com> wrote:
>>>>>> 
>>>>>> typealias AnyObject = … is nice to have, but how about if we fully drop the class constraint-keyword and generalize AnyObject instead?
>>>>>> 
>>>>> That’s a good point. My *technical* goal is for AnyObject to cease to be a protocol, because it’s really describing something more fundamental (“it’s a class!”). Whether we spell that constraint as “class” or “AnyObject” doesn’t affect that technical goal.
>>>>> 
>>>>> I’d gravitated toward the “class” spelling because the idea of a class constraint seems most naturally described by “class”, and it’s precedented in C#.
>>>>> 
>>>>> However, the changes in SE-0095 to make “Any” a more fundamental type (and not just a typealias) definitely open the door to doing the same thing with “AnyObject”—just make it a built-in notion in the language, and the spelling for a class constraint. It *certainly* works better with existentials.
>>>>> 
>>>>>> In the future we might want to add AnyValue with value (semantics) constraint, would that mean that we’d need another keyword there like value?
>>>>>> 
>>>>> “value” would be a terrible keyword, as you know. Point taken :)
>>>>> 
>>>>> If we did something like this, we would probably want it to be akin to ValueSemantics—not just “it’s a struct or enum”, but “it provides value semantics”, because not all structs/enums provide value semantics (but immutable classes do).
>>>>> 
>>>>>> Speaking of the future directions:
>>>>>> 
>>>>>> Now that we’re no longer supporting the idea of Any<…> syntax and any type prefixed with Any seems to be special for its particular usage, could we safely bring the empty Any protocol back (is this somehow ABI related?)?
>>>>>> 
>>>>> From an implementation standpoint, the choice to make AnyObject a magic protocol was a *horrible* decision. We have hacks throughout everything—the compiler, optimizers, runtime, and so on—that specifically check for the magic AnyObject protocol. So, rather than make Any a magic protocol, we need to make AnyObject *not* magic.
>>>>> 
>>>>>> One day after this proposal is accepted, implemented and released, we probably will talk about the where clause for existentials. But since a lot of the existentials will have the form typealias Abc = …, this talk will also include the ability to constrain generic typealiases.
>>>>>> 
>>>>> By “one day” I suspect you mean “some day” rather than “the day after” :)
>>>>> 
>>>>> Yes, I feel like this is a natural direction for existentials to go.
>>>> 
>>>> Looking ahead to when this is on the table, I'm a little worried about the syntactic implications of constrained existentials now that the Any<> syntax doesn't seem to be as popular. The obvious way to go would be
>>>> 
>>>> 'X & Y where …'
>>>> 
>>>> But that leads to ambiguity in function declarations
>>>> 
>>>> func doTheThing<T>() -> X & Y where … where T == …
>>>> 
>>>> This could be resolved by requiring constrained existentials to be typealiased to return them, but I don't think there's any other situations where we require a typealias to use something, and it just feels like a workaround.
>>> 
>>> Types can be parenthesized, so that’s a workaround. But I too have some concerns here that we’re creating an ambiguity that users will trip over.
>> 
>> On top of the ambiguity, I’m really sad that we dropped the Any<A, B, C> syntax because we lost the parallel to inheritance clauses which use the comma as separating character. They both represent similar concepts: a type inheriting and conforming and an existential represent all types which inherit and conform.
>> 
>> I’ve got to ask, is there any chance that either of the two could happen:
>> 
>> 1) Bring back the Any<A, B, C> syntax instead of A & B & C?
>> 2) Replace the inheritance clause X : A, B, C to X : A & B & C?
> 
> Both are possible, as is
> 
> (3) Let A & B & C be a shortcut syntax for Any<A, B, C>, such that Any<…> is the more general version that also permits where clauses, “class” constraints, etc.
> 
> Note that (2) would kill me ;)
> 
>> I know that both are severely source-breaking changes, but either of those would simplify the language by using the same syntax for two very similar concepts. Plus, number 1 would allow us to disambiguate function declarations. I know many people would rejoice having Any<> back.
> 
> Yes, they’re both significant source breakage. It’s source breakage of the “easy” kind, which only affects parsing and therefore makes it easy to keep supporting the Swift 3 syntax in Swift 4.
> 
> (3), on the other hand, isn’t a simplification at all… it’s admitting redundant syntax to avoid source breakage.
> 
> 	- Doug
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170206/2a990486/attachment.html>


More information about the swift-evolution mailing list