[swift-evolution] [Pitch] merge types and protocols back together with type<Type, Protocol, ...>

Matthew Johnson matthew at anandabits.com
Fri May 13 19:16:50 CDT 2016


> On May 13, 2016, at 2:14 PM, Adrian Zubarev via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> As we can(as example) expect that in 3rd party code someone will do: 
>> 
>> extension StructA: ExtraProtocol1 { 
>> func bar() {} 
>> } 
>> 
>> extension StructB: ExtraProtocol2 { 
>> func blort() {} 
>> } 
> 
> 
> Can we really do that? I mean, I thought about that myself but I came to the conclusion that this scenario is like: I was to lazy to couple this structs to my library protocols, will you do that for me?
> 
> Sure one could think that this protocols might be optional but the `f(p: MyProtocol)` function will cover this scenario.
> 
> Another interesting side-effect `struct<>`, `class<>` and `enum<>` will allow us to do is to distinguish between value and reference types for generics. I tried this differentiation types with protocols like `AnyReference` and `AnyValue` in another topic before (Should we rename "class" when referring to protocol conformance? <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016286.html>), but I kinda like this new approach.
> 
> Here is what I mean in detail:
> 
> protocol SomeProtocol /* we can’t constraint it to value types at the moment, only `class`es works */ {}
> 
> func foo<T>(value: struct<T, SomeProtocol>) { /* do some work */ }
> 
> This function is pretty neat. (1) You can force the library user to create a struct with conformance to `SomeProtocol`. (2) This approach will accept any struct which conforms to that protocol.
> 
> As I said in the protocol comment above protocols can only be constrained to classes at the moment, and this might change in the future. If we also had some sort of things for generics so the function from above might have looked like this:
> 
> func foo<T: struct where T: SomeProtocol>(value: T) {}
> 
> But it seems that such a thing won’t ever happen to Swift.
> 
> Basically `struct<>`, `class<>` and `enum<>` will just enable this for us. `all<>` would accept any type at its first element.
> 
> func foo<T /* add more constraints here */ >(value: all<T, SomeProtocol>) { /* T could be a reference type or value type */ }
> 
> That been said, `all<>` could replace `protocol<>` where it is composed from protocols. `all<>` can only be used as a generic constraints if the first element is a protocol or a reference type.
> 
> @Matthew: isn’t this somehow a step towards (generic) `PureValue` types?

No.  These say nothing about semantics.  PureValue is all about the semantics of a type and has nothing to do with what mechanism is used to implement the type.

> 
> struct A<T> {
> 
>     var value: struct<T> // if we drop the strict rule of at least one protocols
> }
> 
> How does it sound to you?
>  
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 13. Mai 2016 bei 20:34:59, Vladimir.S (svabox at gmail.com <mailto:svabox at gmail.com>) schrieb:
> 
>> Hmm.. 
>> 
>> What about such synthetic scenario: 
>> 
>> at the moment of writing our code we have: 
>> 
>> public protocol MyProtocol { 
>> func foo() 
>> } 
>> 
>> public struct StructA:MyProtocol { 
>> func foo() 
>> } 
>> 
>> public struct StructB:MyProtocol { 
>> func foo() 
>> } 
>> 
>> and have 
>> 
>> public protocol ExtraProtocol1 { 
>> func bar() 
>> } 
>> 
>> public protocol ExtraProtocol2 { 
>> func blort() 
>> } 
>> 
>> then we actually can have such code: 
>> 
>> func f(p: MyProtocol) { 
>> if let a = p as? struct<StructA, ExtraProtocol1> { 
>> a.foo() 
>> a.bar() 
>> } 
>> else 
>> if let b = p as? struct<StructB, ExtraProtocol2> { 
>> b.foo() 
>> b.blort() 
>> } 
>> } 
>> 
>> 
>> 
>> 
>> On 13.05.2016 20:50, Adrian Zubarev via swift-evolution wrote: 
>> >> 'struct<>' does seem redundant unless it becomes subtypeable. If 
>> >> you want a struct which conforms to several protocols, protocol<> 
>> >> already covers this. 
>> >> 
>> >> I think this is not correct. Lets check this example: 
>> >> 
>> >> func foo(value: SomeProtocol) { 
>> >> 
>> >> if let a = value as? struct<StructA, SomeProtocol> { /* do 
>> >> something with a */ } 
>> >> 
>> >> else if let b = value as? struct<StructB, SomeProtocol> { /* do 
>> >> something with b */ } 
>> >> 
>> >> } 
>> >> 
>> >> In this scenario you’ll be able to access properties and functions 
>> >> from `StructA` or `StructB` which might not be covered by 
>> >> `SomeProtocol`. Everything is merged nicely into one instance. But 
>> >> you are right it depends on the use-case. 
>> >> 
>> >> 
>> >> There is no need to include the protocol here. Just do this: 
>> >> 
>> >> if let a = value as? StructA { use a } 
>> >> 
>> > Whoops, I forgot that this will do the trick. I apologize for any confusion 
>> > here, you are totally right. 
>> > 
>> > That been said, do we really need `type<>` aka. `all<>` for value types? I 
>> > need to rethink this part of the proposal. Is there any use-case where we 
>> > would need this (any scenario for the future Swift version also counts)? 
>> > 
>> > If we had `all<>` in Swift already for extendable reference types and one 
>> > day structs would become subtypeable, this wouldn’t be a huge problem to 
>> > upgrade `all<>` for structs I guess. 
>> > 
>> > -- 
>> > Adrian Zubarev 
>> > Sent with Airmail 
>> > 
>> > 
>> > 
>> > _______________________________________________ 
>> > swift-evolution mailing list 
>> > swift-evolution at swift.org 
>> > https://lists.swift.org/mailman/listinfo/swift-evolution 
>> > 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160513/0d832263/attachment.html>


More information about the swift-evolution mailing list