By conforming my type to a "ExpressibleBy...Literal" protocol:
struct S {
var x, y, z: Int
}
I can initialise it like so:
let s: S = ["x": 1, "y": 2, "z": 3] // via ExpressibleByDictionaryLiteral
let s: S = [1, 2, 3] // via ExpressibleByArrayLiteral
let s: S = "1, 2, 3" // via ExpressibleByStringLiteral
A notable omission is an ability to do it via a tuple:
let s: S = (1, 2, 3) // via ExpressibleByTupleLiteral?
Shouldn't we have it in Swift for consistency and completeness?
FWIW, this might have an impact on type checker performance. One reason nested collection literals are challenging is that dictionaries, arrays, strings and numbers are all polymorphic literals, which means the type checker cannot immediately assume their type; we must infer it by solving some other constraint. The default type constraint (Int, String, etc) cannot be applied until all other possibilities have been exhausted. Today tuple literals are immediately assigned a type; the element types might be type variables, but the type of the literal is concrete, which allows solving some constraints sooner than if the tuple literal's type was a variable (for example, tuples don't conform to protocols, so we can rule out certain overloads immediately).
For example depending on what is known about the types of x/y and foo, type checking (x, y) == foo would need to check every overload of ==, because some possible solutions might involve those types being ExpressibleByTupleLiteral.
a few years ago we tried to make tuples Equatable and Hashable, which was (as it is now) a major pain point since 1) that precludes using a tuple as a dictionary key, and 2) having a single tuple field in a struct prevents the struct itself from receiving a synthesized Equatable conformance.
However in my original post I'm talking about a scenario where one overload requires a generic type conforms to P, and the user passes in a tuple literal. Even if concrete tuples don't conform to P because there's no tuple conformance, you can't rule out the overload until you rule out the possibility that the type of the literal is something conforming to ExpressibleByTupleLiteral.
one thing worth noting is that such a protocol should probably have a variadic associatedtype TupleLiteralElement
// just bike shedding the syntax here
public protocol ExpressibleByTupleLiteral<each TupleLiteralElement> {
each associatedtype TupleLiteralElement
init(tupleLiteral: (repeat each TupleLiteralElement))
}
Before now we would not have been able to do this. (Actually, we still can't but I assume variadic associated types are coming soon)