[swift-evolution] [Discussion] Parameter `vector` keyword vs. triple dot prefix for variadic generics

Adrian Zubarev adrian.zubarev at devandartist.com
Tue Nov 22 07:24:32 CST 2016


From my imagination, by the time we’ll have variadic generics in Swift one would assume to be able to write own variadic generic enums, but without the pitched auto wrapping feature, and probably without the index of the parameter.

Bikeshedding:

enum MyEnum<vector T> {
     
    vector case name(T)
}
As for my second thought, allowing auto wrapping for every enum seems like an overkill.

For instance

enum Test {
    case a(Int, Int)
    case b(Int, Int)
}

let test: Test = (0, 1) // You might really want here `b(0, 1)` and not `a(0, 1)`
Therefore a single Wrapped type that would support this auto wrapping would come handy. We already have auto wrapping for Optionals. Wrapped would be a second enum that supports this behavior.

Btw to make Wrapped not wrap a single value we’d make it like this:

enum Wrapped<T, vector U> {

    case 0(T)
    vector case #(U) // make # somehow start from +1
}


-- 
Adrian Zubarev
Sent with Airmail

Am 22. November 2016 um 14:00:20, Adrian Zubarev (adrian.zubarev at devandartist.com) schrieb:

The problem I run into where only something similar as described could safe me is as follows.

I’ve got a type Document which is like an ordered dictionary of [String: Value] where Value is my custom value type. I also have a protocol ValueConvertible. Now I want to use the protocol with ExpressibleByDictionaryLiteral in my Document. The Value type is an enum and can also wrap a Document.

The problem that I get here is when creating nested dictionary literals.

// This works just fine with only with
// `public init(dictionaryLiteral elements: (String, Value)...)`

let valueConverible: ValueConvertible = …   

let document: Document = [
    "double": 2.0,
    "string": "test",
    "document": [
        "level": 1,
        "document": ["level": 2]
    ],
    "array": [1, 2, 3],
    "bool": true,
    "int64": 42,
    "doc": [["key": 1]],
    "HERE": valueConverible.value // <— get a `Value` from the computed property.
]
Instead I want a more natural way.

// For // `public init(dictionaryLiteral elements: (String, ValueConvertible)…)`

let document: Document = [
    "double": 2.0,
    "string": "test",
    "document": [
        "level": 1,
        "document": ["level": 2]
    ], // Error `Dictionary` does not conform to `ValueConvertible`
    "HERE": valueConverible // It will unwrap the value inside the initializer.
]
Now I lost nested dictionaries. You may think that something like extension Dictionary : ValueConvertible where Key == String, Value == ModuleName.Value will solve the issue here. But that’s not true because a Dictionary as a default type for dictionary literals is unordered, where the order from my literal is needed to be strict.

Now assume that I’d have Wrapped.

// For // `public init(dictionaryLiteral elements: (String, Wrapped<Value, ValueConvertible>)…)`

let document: Document = [
    "double": 2.0,
    "string": "test",
    "document": [
        "level": 1,
        "document": ["level": 2]
    ], // Fine, compiler is happy again. `Value` conforms to `ExpressibleByDictionaryLiteral`
    "HERE": valueConverible // fine
]
To me it would be enough if Wrapped would match types from left to right.

let x: Wrapped<A, B, C> = b // checks A -> fails, checks B, fine wrap into `Wrapped<A, B, C>.1(b)`
Again even we’d allow Wrapped<A, A> the compiler would walk from left to right during the matching process, and never reach the .1(A) when wrapping an instance of A. This last example is simply useless but it makes Wrapped simple.

Basically I imagine Wrapped like this:

enum Wrapped<A, B> {
    case 0(A)
    case 1(B)
}

enum Wrapped<A, B, C> {
    case 0(A)
    case 1(B)
    case 2(C)
}

enum Wrapped<A, B, C, D> {
    case 0(A)
    case 1(B)
    case 2(C)
    case 3(D)
}

…

// or simply
enum Wrapped<vector T> {
      
    vector case #(T)
}
Wouldn’t sucht a type come handy in other areas as well? Any idea?

If not Wrapped, so what about the first pitch of allowing implicitly wrap enums?



-- 
Adrian Zubarev
Sent with Airmail

Am 22. November 2016 um 12:49:39, Karl (razielim at gmail.com) schrieb:

So you want a variadic enum whose cases are bound by the number of generic type parameters. The cases would all need to be unique types, or your assignment syntax wouldn’t work. I’m guessing you want to avoid the boilerplate of having several enums with different names, so you want to merge them all in to one enum you can use everywhere.

Effectively, what you end up with is indistinguishable from an anonymous logical OR type which the core team have expressly said they don’t want in Swift. For that reason I’m -1 on the `Wrapped` idea.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161122/9cb8ec0f/attachment.html>


More information about the swift-evolution mailing list