# Making tuples more useful with ExpressibleByTupleLiteral?

**URL:** <https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248>\
**Category:** Pitches\
**Created:** [March 21, 2018, 11:16pm UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248 "2018-03-21T23:16:08Z")\
**Posts on this page:** 18\
**Page:** 1

<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 21, 2018, 11:16pm UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/1 "2018-03-21T23:16:08Z")

</div>

Consider:

```swift
struct Point {
    let x: Int
    let y: Int
}

let point = Point(x: 1, y: 1)

```

For such a simple type, this sort of verbosity can be quite annoying. So, is there any interest in adding an `ExpressibleByTupleLiteral` protocol, which would allow us to write `let point: Point = (1, 1)`, and even cleaner statements when passing directly into functions or any context where the type is already known. For instance, being able to express `[Point]` as `[(0, 0), (1, 1), (2, 2)]` would be nice.

There are a few additional details, like whether (or how) labeled tuples would be supported or not, or perhaps required, and whether element order would matter if they were labeled.

---

<div class="post-metadata">

**Author:** ![mylin](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@mylin](https://forums.swift.org/u/mylin)\
**Post date:** [March 22, 2018, 12:14am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/2 "2018-03-22T00:14:19Z")

</div>

Based on your motivation, maybe a more direct solution would be to allow the compiler to infer a `.init` on a tuple. Right now we can actually do things like

```nohighlight
extension Point {
    init(_ x: Int, _ y: Int) {
        self.x = x
        self.y = y
    }
}

let point: Point = .init(1, 1)
let pointArray: [Point] = [.init(0, 0), .init(1, 1), .init(2, 2)]

```

It would be interesting if initializers were special-cased, so that we could just supply tuples (potentially with labels) and have them called automatically.

---

<div class="post-metadata">

**Author:** ![leehericks](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/leehericks/32/2819_2.png) [@leehericks](https://forums.swift.org/u/leehericks)\
**Post date:** [March 22, 2018, 12:42am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/3 "2018-03-22T00:42:41Z")

</div>

I like this proposal. I think labeled init parameters is very self-documenting, but Jon raises a good point about when sometimes we'd like that stuff to fade away for general structures.

But rather than the original tuple proposal, I like Lucas's suggestion to just allow simplifying init. At least in that case type and argument types and order could be inferred right?

Would this only be applicable to structs or would classes behave the same?

---

<div class="post-metadata">

**Author:** ![mylin](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@mylin](https://forums.swift.org/u/mylin)\
**Post date:** [March 22, 2018, 1:15am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/4 "2018-03-22T01:15:39Z")

</div>

I personally see no good reason why this rule should only apply to `struct` types, though I did miss that no `init(_, _)` had been defined originally for `Point`; I've updated my post appropriately.

Even with this kind of shorthand, I think that argument labels would need to be kept as usual when eliding the `.init`. Not requiring this could lead to serious ambiguities for initializers overloaded on argument labels, of which there are a lot, and in general I think Swift's labeling is a Good Thing™. If someone wants their type to be initialized by a tuple without argument labels, they should be required to provide an appropriate initializer.

Thinking about how this could be generalized to non-tuples as well, I've arrived at the following C++ inspired idea:

### The Idea

What if we added a new keyword, `implicit`, that could prefix an initializer? For instance:

```Swift
struct Point {
    let x: Int
    let y: Int

    implicit init(_ x: Int, _ y: Int) { ... }
}

```

For initializers taking multiple parameters, an `implicit` qualifier would allow the aforementioned elision of the `.init`, allowing direct initialization from a tuple literal. For unlabeled initializers taking one parameter of type `T`, an implicit initialization could be performed from any `T` (basically implicit casts).

Even more interestingly, we could allow the `implicit` prefix on enum cases:

```Swift
enum JSONValue {
    case null
    implicit case number(Double)
    implicit case string(String)
    ...
}

// This would be valid (interpreted as a .number(4) instance):
let foo: JSONValue = 4

```

This would also allow the automatic conversion from `T` to `T?`, which is currently one of the magical aspects of `Optional`, to be done through a basic language feature.

---

<div class="post-metadata">

**Author:** ![anthonylatsis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anthonylatsis/32/39232_2.png) [@anthonylatsis](https://forums.swift.org/u/anthonylatsis)\
**Post date:** [March 22, 2018, 1:46am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/5 "2018-03-22T01:46:37Z")

</div>

For simple types like `Point` this is a great convenience. Once types and initializers become more complex, this can become a unreadable mess that is impermissible in Swift and it's syntax. This especially applies to using a value for initialization:

```swift
func foo(view: UIView) ...

foo(view: CGRect.init(x: 0, y: 5, width: 100, height: 50)) 

```

Enums are tricky as well. There is no solution other than not making `implicit` cases with equal associated value types.

That said, the best option is not to expose this, having an internal `ExpressibleByTupleLiteral` that can be made use of where needed just like `ExpressibleByColorLiteral`.

Moreover, the chance of the latter not affecting ABI is much higher than the introduction of a new keyword.

---

<div class="post-metadata">

**Author:** ![mylin](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@mylin](https://forums.swift.org/u/mylin)\
**Post date:** [March 22, 2018, 2:36am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/6 "2018-03-22T02:36:20Z")

</div>

> [@anthonylatsis](#):
>
> Once types and initializers become more complex, this can become a unreadable mess that is impermissible in Swift and it’s syntax. This especially applies to using a value for initialization:
> 
> ```Swift
> func foo(view: UIView) ...
> 
> foo(view: CGRect.init(x: 0, y: 5, width: 100, height: 50))
> 
> ```

This is why I suggested an `implicit` keyword, making _explicit_ conversions the default. In many, many cases, like the one you've pointed out here, implicit conversion simply doesn't make sense, so we can simply not have `implicit` initializers in those cases. We already allow omission of parameter labels at the API author's discretion; I don't see this as being substantially different.

* * *

> [@anthonylatsis](#):
>
> Enums are tricky as well. There is no solution other than not making implicit cases with equal associated value types.

A good point, though I'm not sure it's a particularly big issue. We could simply make those ambiguous `implicit case`s illegal, as you suggest.

* * *

> [@anthonylatsis](#):
>
> That said, the best option is not to expose this, having an internal ExpressibleByTupleLiteral that can be made use of where needed just like ExpressibleByColorLiteral.

Without generic protocols, this would only allow conversion from one distinct tuple type, per conformer. This also fails to cover implicit conversions from single-element-(i.e. non-)tuples, which I still think are a valuable use case.

* * *

> [@anthonylatsis](#):
>
> Moreover, the chance of the latter not affecting ABI is much higher than the introduction of a new keyword.

Perhaps I'm naive, but I don't see how a keyword like `implicit` would require any changes to the Swift ABI _in general_. Since it's an opt-in, it would have no effect whatsoever on existing code, and I can't think of any effect of `implicit` on the way an initializer would need to be called.

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [March 22, 2018, 3:20am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/7 "2018-03-22T03:20:14Z")

</div>

I've always thought that ExpressibleByTupleLiteral would be a great addition. I don't see a lot of value in tying this to some sort of automatic succinct initialiser feature, or introducing user-defined implicit conversions. The latter were already removed from Swift once, and I don't see much appetite on the implementation side for adding them back in, so I hope this thread won't get too sidetracked by that.

The obvious implementation of just having it behave like any other `ExpressibleByLiteral` type seems ideal to me if there are no practical issues. This won't be an implicit conversion (you will have the write the literal directly in the relevant context), and will just handle a single tuple type, like the other literal protocols, by using an associated type.

---

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [March 22, 2018, 10:11am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/8 "2018-03-22T10:11:35Z")

</div>

Wouldn't `ExpressibleByTupleLiteral` be possible only with variadic generics?

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [March 22, 2018, 11:17am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/9 "2018-03-22T11:17:34Z")

</div>

I'm probably missing something, but I don't understand why. The tuple would just be an associatedtype in the protocol and received as a single tuple argument to the `init(tupleLiteral:…)` initialiser. The conforming type wouldn't need to be generic at all, neither would the initialiser, and the protocol can't be. Where is the variadic generic?

---

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [March 22, 2018, 11:38am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/10 "2018-03-22T11:38:01Z")

</div>

How would you define the signature of the `init` inside the protocol? Maybe I am missing something as well but I don't see ways of doing it without that functionality...

You could do something like

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

```

But it doesn't ensure it's a tuple, so it kinda defeats the concept.

You can also do something like

```swift
protocol ExpressibleByTupleLiteral {
    associatedtype TupleElement
    init(tupleLiteral: TupleElement...)
}

```

But it supports only tuples with elements of the same type, which limits it greatly...

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [March 22, 2018, 11:57am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/11 "2018-03-22T11:57:38Z")

</div>

All the literal protocols are necessarily somewhat implemented in, and coupled with, the compiler, which could ensure that the `Tuple` type in your first example is a tuple. You're right that you can't write this constraint on `Tuple` in the language currently, though, but I don't think that's necessarily related to variadic generics.

---

<div class="post-metadata">

**Author:** ![MutatingFunk](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mutatingfunk/32/984_2.png) [@MutatingFunk](https://forums.swift.org/u/MutatingFunk)\
**Post date:** [March 23, 2018, 12:16am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/12 "2018-03-23T00:16:15Z")

</div>

I think initialisation from a tuple makes sense only for memberwise initialisers. As soon as you get side-effects, or (to some extent) defaulted members, tuples just end up being confusing.

If we had some way of generating memberwise initialisers for any type, or otherwise marking initialisers as memberwise, this could work very well as a convenience on top of that.

I also like the idea of generalising this to enums, and removing some of the magic of optional in the process.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [March 23, 2018, 3:52am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/13 "2018-03-23T03:52:10Z")

</div>

> [@MutatingFunk](#):
>
> If we had some way of generating memberwise initialisers for any type, or otherwise marking initialisers as memberwise, this could work very well as a convenience on top of that.

Flexible memberwise initializers were the subject of SE-0018:

> <https://github.com/apple/swift-evolution/blob/main/proposals/0018-flexible-memberwise-initialization.md>

---

<div class="post-metadata">

**Author:** ![ahti](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ahti/32/604_2.png) [@ahti](https://forums.swift.org/u/ahti)\
**Post date:** [March 23, 2018, 6:52am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/14 "2018-03-23T06:52:45Z")

</div>

I had a similar idea a few months ago that might be a good way to tackle this. Assuming this `Point` struct:

```swift
struct Point {
    let x: Int
    let y: Int

    static let zero = Point(x: 0, y: 0)
}

```

We can already do this:

```swift
let p: Point = .init(x: 42, y: 420)

```

My idea would be to allow omitting the `init` part, leaving us with:

```swift
let p: Point = .(x: 42, y: 420)

```

Since the leading dot is already established as accessing a static member of the inferred type, I think this is quite a natural extension. Comparing the existing leading dot syntax with my proposed syntax:

```swift
let a1 = Point.zero
let a2: Point = .zero

let b1 = Point(x: 42, y: 420)
let b2: Point = .(x: 42, y: 420)

```

Imo, this would be more useful than normal tuples plus a protocol because you could use any initialiser, including extending existing types with your own. The leading dot also clearly distinguishes it from normal tuples, avoiding confusion.

---

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [March 23, 2018, 10:36am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/15 "2018-03-23T10:36:55Z")

</div>

While the `.(...)` syntax might be nicer, I don't think it gives enough improvement in respect to `.init(...)` to warrant a change.  
I know theres a bit of asymmetric design here, where `Type(...)` works without the need for `Type.init(...)`, and I usually get slightly annoyed by that, but I still don't feel it's something worth doing...

---

<div class="post-metadata">

**Author:** ![SwiftStudies](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/swiftstudies/32/5077_2.png) [@SwiftStudies](https://forums.swift.org/u/SwiftStudies)\
**Post date:** [March 23, 2018, 11:38am UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/16 "2018-03-23T11:38:36Z")

</div>

I like this idea. I agree there should be no need to restrict to value types.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [March 23, 2018, 3:00pm UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/17 "2018-03-23T15:00:38Z")

</div>

The review of my Flexible Memberwise Initialization proposal led to a lot of good ideas. This topic fits nicely with the recent series of proposals which provide complier synthesis of boilerplate. I would like to revisit the topic with a new design that considers the feedback of the prior review when the time is right (i.e. when an implementing collaborator appears).

---

<div class="post-metadata">

**Author:** ![KyLeggiero](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kyleggiero/32/47024_2.png) [@KyLeggiero](https://forums.swift.org/u/KyLeggiero)\
**Post date:** [August 2, 2019, 8:59pm UTC](https://forums.swift.org/t/making-tuples-more-useful-with-expressiblebytupleliteral/11248/18 "2019-08-02T20:59:51Z")

</div>

Wow this went nowhere, huh? Over a year later and I'd love to see this for all the use cases described here.

I feel like the improvements to Swift 5.1's synthesized initializers with default values rather makes SE-0018 irrelevant, but still doesn't address this at all.
