[swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol<P1, P2> syntax with Any<P1, P2>

Adrian Zubarev adrian.zubarev at devandartist.com
Wed May 25 02:38:28 CDT 2016

I’ll read closely all the feedback we’ve got here so far and comment when I’m done with my work today.

Here is the future direction part from the other proposal we haven’t submitted yet, where I believe Joe mentioned a few words in that direction:

Future directions

any<...> should reflect powerful generalized generic features to be able to constrain types even further (e.g. where clause).

Adding constraints for other extendable types like struct and enum and generalize these. This will allow us to form more typealiases like:

typealias AnyStruct = any<struct>
typealias AnyEnum = any<enum>
protocol A { func boo() }

// Structs that conforms to a specific protocol.
func foo(value: any<struct, SomeProtocol>)  
func foo(value: any<AnyStruct, SomeProtocol>)  
// Enums that conforms to a specific protocol.
func foo(value: any<enum, SomeProtocol>)  
func foo(value: any<AnyEnum, SomeProtocol>)  
// Lets say this array is filled with structs, classes and enums,
// which all conforms to `SomeProtocol`.
let array: [SomeProtocol] = // fill

// Filter these types:
var classArray: [any<class, SomeProtocol>] = array.flatMap { $0 as? any<class, SomeProtocol> }
var structArray: [any<struct, SomeProtocol>] = array.flatMap { $0 as? any<struct, SomeProtocol> }
var enumArray: [any<enum, SomeProtocol>] = array.flatMap { $0 as? any<enum, SomeProtocol> }
Flattened operators or even Type operators for any<...>:

class B {
    var mainView: UIView & SomeProtocol
    init(view: UIView & SomeProtocol) {
        self. mainView = view
The & type operator would produce a “flattened" any<> with its operands. It could be overloaded to accept either a concrete type or a protocol on the lhs and would produce Type for an lhs that is a type and any<...> when lhs is a protocol. Type operators would be evaluated during compile time and would produce a type that is used where the expression was present in the code. This is a long-term idea, not something that needs to be considered right now.

Written by: Matthew Johnson
Adding one<...> which can reduce overloading (idea provided by: Thorsten Seitz). one<...> will pick the first type match from within the angle brackets to the dynamic type at compile time and proceed. One would then need to handle the value by own desire.

func foo(value: one<String, Int>) {
    if let v = value as? String {
        // Do some work
    } else if let v = value as? Int {
        // Do some work
// Flattened version:
func foo(value: String | Int)
Mix any<...> and one<...>:

// Accept only types constrained by  
// (`ClassA` AND `SomeProtocol`) OR (`ClassB` AND `SomeProtocol`)
func foo(value: any<one<ClassA, ClassB>, SomeProtocol>)

// Flattened version:
func foo(value: (ClassA | ClassB) & SomeProtocol)
Typealias AnyValue (for extendable types only):

// Isn't this like magic
typealias AnyValue = one<any<struct>, any<enum>>  
typealias AnyValue = one<AnyStruct, AnyEnum>
typealias AnyValue = any<struct> | any<enum>
typealias AnyValue = AnyStruct | AnyEnum

// Any value which conforms to `SomeProtocol`.
// Reference types are finally out the way.
func foo(value: any<AnyValue, SomeProtocol>)  

// Flattened version:
func foo(value: AnyValue & SomeProtocol)

one<…> is a different story, so don’t stick with it too much in this discussion.

@Austin: If you’re going to update the future direction of this proposal you may want to use something from the future direction part I just posted.

Adrian Zubarev
Sent with Airmail
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160525/6d0d2828/attachment.html>

More information about the swift-evolution mailing list