[swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

Matthew Johnson matthew at anandabits.com
Fri May 27 16:13:06 CDT 2016

Sent from my iPad

> On May 27, 2016, at 3:43 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> On May 24, 2016, at 9:35 PM
> on Tue May 24 2016, Matthew Johnson <swift-evolution at swift.org> wrote:
>> , Austin Zheng
>> <austinzheng at gmail.com> wrote:
>>    On Tue, May 24, 2016 at 4:24 PM, Brent Royal-Gordon
>>    <brent at architechies.com> wrote:
>>> I’m not sure what you mean about introducing type unsafely.
>>        What I mean is that once you do this:
>>        let x: AnyCollection<Character> = myArrayOfCharacters
>>        let y: AnyCollection<Character> = myString.characters
>>        Both `x` and `y` have indices of type `Any<Comparable>`, and will now
>>        accept each others' indices:
>>        for i in x.indices {
>>        print(y[i]) // Oops!
>>        }
>>        If this rule:
>>> The generalized existentials proposal goes out of its way to be
>>        explicit about the fact that only type safe operations would be visible
>>        through the existential.
>>        Is trying to say that this isn't the case because APIs using the
>>        collection's `Index` are not exposed on an `AnyCollection`, well, then
>>        I'm not sure what `AnyCollection` is actually supposed to be used for.
>>    If there's any way that the rules that I've proposed can be relaxed without
>>    sacrificing type safety, I would love to hear it. I think the difference in
>>    'power' in this regard between a function that uses generic types and a
>>    function that uses existentials is something inherent to how each works,
>>    though.
>> The primary difference is the freedom to accept an index which is invalid and
>> call fatalError when you get it. We don't want existentials to do something
>> that. But with user-defined types we have the flexibility to do that if we
>> decide it is the right design.
> I'm not sure I agree that Existentials shouldn't do that.  The amount of
> boilerplate one needs to construct a user-defined simulation of an
> existential in these cases can be prohibitive.  Why shouldn't the
> compiler handle it for us?

I know it involves a lot of boilerplate that is better avoided and can be prohibitive and steer one away from designs that might otherwise be useful.

But the behavior of AnyCollection (specifically AnyIndex) involves custom logic that decides where and how to introduce the potential for fatalError.  I definitely don't want the compiler doing this without an explicit request of some kind.  Existentials should at least be safe by default.  If we *really* need a way to introduce unsafe existentials it should be opt-in (I have no idea what that might look like).  But I'm not sure it's worth introducing a feature like that just to make it easier to create types with an unsafe interface.

But why would you want the unsafe behavior of AnyCollection when we could have a safe 'typealias AnyCollection<T> = Collection where .Element == T'?  You would be able to safely use indexes received from the collection to index back into it.  Usage that would cause a runtime crash can be caught at compile time.  The only thing you wouldn't be able to do is take an index received from one collection and use with another.  Is there a specific use case the current design supports that the safer existential would not?


> -- 
> Dave
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

More information about the swift-evolution mailing list