# Implementing ExpressibleByTupleLiteral: how hard?

**URL:** <https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169>\
**Category:** Compiler\
**Created:** [March 3, 2019, 8:54pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169 "2019-03-03T20:54:55Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 3, 2019, 8:54pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/1 "2019-03-03T20:54:56Z")

</div>

asking someone who’s more knowledgeable about the compiler than i am, how difficult would it be to implement `ExpressibleByTupleLiteral`? the approach i’m considering is to use a `TupleType` protocol which all tuples conform to as a constraint on `Self.TupleLiteralType` which would sidestep the need for variadic generics.

I’ve built the compiler and i’m proficient in C++ but i’ve never really delved into the compiler internals so I’d like to know what i’d be getting into

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [March 3, 2019, 8:59pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/2 "2019-03-03T20:59:03Z")

</div>

The big problem that you're going to run into here is that tuples are not "nominal types", which practically means that there's nowhere to attach the conformance to your hypothetical protocols. My understanding is that it doesn't _have_ to work that way, but there's a lot of things that would have to change in order for the language to behave differently.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 3, 2019, 9:01pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/3 "2019-03-03T21:01:20Z")

</div>

maybe this is a really dumb question but can’t `TupleType` just be a magic compiler protocol that all tuples automatically conform to?

---

<div class="post-metadata">

**Author:** ![hartbit](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hartbit/32/738_2.png) [@hartbit](https://forums.swift.org/u/hartbit)\
**Post date:** [March 3, 2019, 9:37pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/4 "2019-03-03T21:37:22Z")

</div>

Wouldn't you need variadic generics to be able to do anything useful with that type?

---

<div class="post-metadata">

**Author:** ![nnnnnnnn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nnnnnnnn/32/264_2.png) [@nnnnnnnn](https://forums.swift.org/u/nnnnnnnn)\
**Post date:** [March 3, 2019, 10:28pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/5 "2019-03-03T22:28:10Z")

</div>

Are you thinking of something like this?

```swift
protocol ExpressibleByTupleLiteral {
    associatedtype TupleLiteralType: TupleType
    init(tupleLiteral: TupleLiteralType)
}

extension CGPoint: ExpressibleByTupleLiteral {
    // implied: typealias TupleLiteralType = (CGFloat, CGFloat)
    init(tupleLiteral: (CGFloat, CGFloat)) { ... }
}

```

If each conforming type specifies a specific tuple type that represents them, then variadic generics wouldn't necessarily be a stumbling block. Instead of making tuples conform to a protocol, it might be simpler to have the compiler recognize the `ExpressibleByTupleLiteral` protocol and simply enforce that `TupleLiteralType` is a tuple type. (I think this would be a less desirable solution, however.)

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 3, 2019, 11:07pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/6 "2019-03-03T23:07:55Z")

</div>

yes, that’s exactly what i’m thinking of. `TupleType` would just be the compiler’s way of exposing that to users.

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [March 4, 2019, 4:59am UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/7 "2019-03-04T04:59:52Z")

</div>

Would this be much different than simply allowing us to skip writing out the `.init`-part of the currently allowed "typenameless initializer": `.init(…)`, so that we could write just `(…)`  
?

That is, Swift currently allow all but the last two of these:

```swift
Rect(origin: Point.init(1, 2), size: Size.init(3, 4))
Rect(origin: Point(1, 2), size: Size(3, 4))
Rect(origin: .init(1, 2), size: .init(3, 4))
Rect(origin: .(1, 2), size: .(3, 4))
Rect(origin: (1, 2), size: (3, 4))

```

Any particular reason why the last (and second to last) can/should not be allowed?

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [March 4, 2019, 5:00pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/8 "2019-03-04T17:00:55Z")

</div>

Another option is to make tuples primary (and still add support for expressible by etc), I mentioned this over on the [variadic generics thread](https://forums.swift.org/t/starting-to-implement-variadic-generics/21159/7) I'm curious to see what @Douglas_Gregor thinks.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [March 4, 2019, 6:15pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/9 "2019-03-04T18:15:58Z")

</div>

I agree with @Jens; I think it'd be better to make tuple syntax a shorthand for initializing a contextual type (like `.init(...)` but without the `.init`) than to introduce a protocol for making certain types able to use tuple syntax. I can see many benefits to this:

- It doesn't need any new fundamental type system features to support the full functionality of tuple syntax, including variable numbers of arguments, preservation of the individual element types, labels, etc., since these can all be expressed as initializer overloads.
- It reduces the friction in migrating a tuple to a named type, if you outgrow the abilities of tuples.
- It would make expressing large, well-typed literals generally more streamlined, since you wouldn't need `.init(...)` or `T(...)` prefixes that can be deduced from context.
- Protocols need runtime support, and any new ones we add will be availability-gated by OS versions with new enough standard libraries to provide them. I think that indicates that protocol requirements are not a great idea for features that are intended primarily as compile-time syntactic conveniences.

A prototype implementation approach to experiment with this design direction would be to set up a constraint system when we see a tuple expression to make a disjunction between forming the tuple or looking for an init member in the contextual type, scoring the tuple case higher as the default.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [March 4, 2019, 6:26pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/10 "2019-03-04T18:26:15Z")

</div>

Are you suggesting that we would allow `(x, y, z)` to construct _any_ type for which those are valid arguments to an initializer? That seems... expressive but incomprehensible if used widely. Maybe there could just be an attribute on an initializer allowing it to be used with tuple literals?

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [March 4, 2019, 6:30pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/11 "2019-03-04T18:30:40Z")

</div>

Sure, that seems like a reasonable approach too.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [March 4, 2019, 6:48pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/12 "2019-03-04T18:48:55Z")

</div>

This seems both inconsistent with Swift's current naming guidelines, as pointed out by @John_McCall, and with Swift's general design philosophy, as evidenced by the rest of the `ExpressibleBy...` protocols. ABI stability may make such things more complicated now, but as a user, I'd rather have that burden handled by the language than break existing language idioms.

If Swift did (it shouldn't, but..) adopt tuple -\> initializer equivalence, argument labels _must_ be preserved, otherwise, what's been the point of all of these naming guidelines?

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [March 4, 2019, 6:54pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/13 "2019-03-04T18:54:11Z")

</div>

In the design I had in mind, you'd use the argument labels of the initializer in the tuple shorthand, so you'd invoke `init(x: Int, y: Int)` as `(x: 1, y: 2)`. If you wanted to be expressible as an unlabeled tuple, you'd provide an init without argument labels. I can certainly see the potential for inscrutability if you used this shorthand too much with unlabeled initializers, but Swift's naming guidelines strongly encourage labels for most initializers, and the labels can provide more context as to what's being initialized, in addition to the context.

As to whether this fits with Swift's general design philosophy, I think there's some sunk cost fallacy to watch out for there. We've avoided adopting protocols for several other syntactic sugar features we've recently added (particularly, dynamic member and call syntax) instead of protocols for similar reasons, and even string interpolation only halfway uses protocols since `appendInterpolation` segments are resolved by ad-hoc overloading.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 4, 2019, 8:09pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/14 "2019-03-04T20:09:55Z")

</div>

> [@Jon\_Shier](#):
>
> ABI stability may make such things more complicated now, but as a user, I'd rather have that burden handled by the language than break existing language idioms.

Joe is right with the sunk costs thing, having pushed the character literals proposal to where it is now, it’s clear to me that using protocols for literal syntax causes a lot of ABI problems that in principle shouldn’t exist for purely syntactical issues. It’s probably too late to strip out the existing `ExpressibleBy` system, but i don’t think it’s a bad idea to stop trying to shoehorn literal syntax features into `ExpressibleBy` protocols.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 4, 2019, 8:13pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/15 "2019-03-04T20:13:05Z")

</div>

> [@John\_McCall](#):
>
> Are you suggesting that we would allow `(x, y, z)` to construct _any_ type for which those are valid arguments to an initializer? That seems... expressive but incomprehensible if used widely. Maybe there could just be an attribute on an initializer allowing it to be used with tuple literals?

i like this idea a lot actually. i was thinking of having a “magic” reserved protocol `ExpressibleByTupleLiteral` which would not be a real protocol but only tell the compiler to enable tuple initialization, but that wouldn’t let us pick _which_ initializer in a type with multiple `init`s. Attribute is definitely the way to go

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [March 4, 2019, 8:19pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/16 "2019-03-04T20:19:09Z")

</div>

It's not about sunk cost but all of the previous language arguments for having those expressible protocols. Rather than bifurcate the language where some literals are done through public protocols and some through random attributes, I'd rather have one unified approach, and I think that would be better for the language as well. When the protocol conformance vs. ABI stability was explained before, it sounded like the language just lacked a mechanism to express new conformances, not that it was impossible. Additionally, `ExpressibleByTupleLiteral` would be a new protocol, and its entire existence would need to be gated. Am I to understand that's an impossibility too, or that the language just doesn't have a good way to express it in an ABI stable way right now?

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [March 4, 2019, 8:26pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/17 "2019-03-04T20:26:04Z")

</div>

While we have to keep the `ExpressibleBy*` protocols for source and ABI stability, it might be worth considering augmenting them with attribute-driven forms too. We could also introduce attributes to allow initializers to be used with the existing literal forms, which would mean we could make Int8 unicode-scalar-expressible without ABI impact:

```swift
extension Int8 {
  @unicodeScalarLiteral // instead of : ExpressibleBy...
  init(unicodeScalarLiteral: Int8) {...}
}

```

---

<div class="post-metadata">

**Author:** ![Alejandro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alejandro/32/46197_2.png) [@Alejandro](https://forums.swift.org/u/Alejandro)\
**Post date:** [March 4, 2019, 8:28pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/18 "2019-03-04T20:28:39Z")

</div>

My thoughts exactly when John mentioned it for tuples. +1

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [March 4, 2019, 8:33pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/19 "2019-03-04T20:33:34Z")

</div>

> [@Jon\_Shier](#):
>
> It's not about sunk cost but all of the previous language arguments for having those expressible protocols. Rather than bifurcate the language where some literals are done through public protocols and some through random attributes, I'd rather have one unified approach, and I think that would be better for the language as well. When the protocol conformance vs. ABI stability was explained before, it sounded like the language just lacked a mechanism to express new conformances, not that it was impossible. Additionally, `ExpressibleByTupleLiteral` would be a new protocol, and its entire existence would need to be gated. Am I to understand that's an impossibility too, or that the language just doesn't have a good way to express it in an ABI stable way right now?

It's not impossible to gate protocols by availability, and it would in fact be easier for a new protocol like ExpressibleByTupleLiteral than @taylorswift's example because we'd be introducing the entire protocol as a new thing, rather than retroactively introducing new conformances of existing types to an existing protocol. Nonetheless, it seems unfortunate to me to subject features whose primary purpose is compile-time sugar to runtime availability constraints. As @Dave\_Abrahams1 likes to say, the existence of a protocol ought to be justified by the kinds of programs you can write against the interface and guarantees a protocol gives you. By themselves, the literal protocols don't really give you much of an API contract to work with, and are of marginal use as generic constraints on their own. As such, from a blank slate they seem like poor candidates for protocols, even putting aside the runtime deployment issues.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [March 4, 2019, 8:45pm UTC](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169/20 "2019-03-04T20:45:26Z")

</div>

It just seems like a sudden, radical shift in language design philosophy from protocols to attributes for this functionality. Not only have attributes been previous eschewed as a common language element to prevent Java-like attribute spew, but this logic flies in the face of pretty much all previous discussion around the `ExpressibleBy` protocols. They were viewed as one of the more elegant parts of the language, (mostly) non-magical, unlike attributes, and giving visibility to this type of functionality. It seems like this sudden shift is being driven by ABI stability and if so, I think does a disservice to the language.

If attributes are to replace the `ExpressibleBy` protocols, it seems like a counterpart to the first proposal to do so should be one to enable attributes for all other `ExpressibleBy` conformances so that code remains consistent. Would that be acceptable?

[Next page](https://forums.swift.org/t/implementing-expressiblebytupleliteral-how-hard/21169.md?page=2)
