# \[Discussion\] Enforce argument labels on tuples

**URL:** <https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273>\
**Category:** Discussion\
**Created:** [April 20, 2016, 1:23pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273 "2016-04-20T13:23:22Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 20, 2016, 1:23pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/1 "2016-04-20T13:23:22Z")

</div>

I would like to discuss about the following topic.

Wouldn't it be better to enforce argument labels on tuples types, if the tuple type defines them?

```swift

func foo(tuple: (a: Int, b: Int)) { /* do something */ }

let test1 = (10, 100)
let test2: (a: Int, c: Int) = test
let test3: (Int, Int) = test2

foo(test1)
foo(test3)

/*
cannot convert value of type '(a: Int, c: Int)' 
to expected argument type '(a: Int, b: Int)'
*/
foo(test2) 

```

Function `foo` awaits a tuple of type `(a: Int, b: Int)` but `test1` and `test3` are both just of type `(Int, Int)`.  
As expected `test2` will raise an error because it has indeed a wrong type `(a: Int, c: Int)`.

I'd suggest to enforce argument labeling on tuple types for better readability, because wasn't it the idea behind labels inside tuples?

`foo(test1)` should raise an error `cannot convert value of type '(Int, Int)' to expected argument type '(a: Int, b: Int)'` as long as `test1` is not written like `let test1 = (a: 10, b: 100)` or `let test1: (a: Int, b: Int) = (a: 10, b: 100)`

This will impact current codebase if you used labels but provided tuples without labels like the example above. The migrator could solve this by providing labels automatically to tuples where this error occurs.

I'm not good at writing proposals for the GitHub repository at all, so if the community likes this idea, I'd be glad to see some help for this little proposal.

> **···**
>
> --  
> Adrian Zubarev  
> Sent with Airmail

---

<div class="post-metadata">

**Author:** ![owensd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/owensd/32/8934_2.png) [@owensd](https://forums.swift.org/u/owensd)\
**Post date:** [April 20, 2016, 7:31pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/2 "2016-04-20T19:31:51Z")

</div>

This is similar to another concern I raised with functions and being able to essentially erase the function argument names and apply two different named parameters just because their types match.

It seems reasonable to me that you can go from (x: Int, y: Int) =\> (Int, Int). However, going from (x: Int, y: Int) =\> (a: Int, b: Int) feels somewhat odd. Yes, the types can obviously slot in there fine, but how much importance do the labels for the types bring to the table?

Similarly, should this (Int, Int) =\> (x: Int, y: Int) be allowed through an implicit means? If so, then it's really just an intermediate step for (x: Int, y: Int) =\> (a: Int, b: Int) working.

So what matters more, type signatures or label names?

Here's an example:

typealias Functor = (left: Int, right: Int) -\> Int

func hi(x: Int, y: Int, fn: Functor) -\> Int {  
&nbsp;&nbsp;&nbsp;&nbsp;return fn(left: x, right: y)  
}

hi(1, y: 2, fn: +)  
hi(1, y: 2, fn: \*)

If we say that the parameter names are indeed vital, then the above code cannot work as the operators that match the type signature are defined as:

public func +(lhs: Int, rhs: Int) -\> Int

Obviously, given a name to the parameter brings clarity and can be self documenting, but if we want the above to work while making names just as vital as the type signature, then we need to declare `Functor` as such:

typealias Functor = (\_ left: Int, \_ right: Int) -\> Int

However, that's not even legal code today, and even if it were, is that really better?

So I'm mixed on the idea. I think the idea that type coercions happening for matching type signatures is very powerful, and this just happens to be one of the example manifestations of that.

-David

> **···**
>
> > On Apr 20, 2016, at 6:23 AM, Adrian Zubarev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I would like to discuss about the following topic.
> > 
> > Wouldn't it be better to enforce argument labels on tuples types, if the tuple type defines them?
> > 
> > ```swift
> > 
> > func foo(tuple: (a: Int, b: Int)) { /* do something */ }
> > 
> > let test1 = (10, 100)
> > let test2: (a: Int, c: Int) = test
> > let test3: (Int, Int) = test2
> > 
> > foo(test1)
> > foo(test3)
> > 
> > /*
> > cannot convert value of type '(a: Int, c: Int)' 
> > to expected argument type '(a: Int, b: Int)'
> > */
> > foo(test2) 
> > 
> > ```
> > 
> > Function `foo` awaits a tuple of type `(a: Int, b: Int)` but `test1` and `test3` are both just of type `(Int, Int)`.  
> > As expected `test2` will raise an error because it has indeed a wrong type `(a: Int, c: Int)`.
> > 
> > I'd suggest to enforce argument labeling on tuple types for better readability, because wasn't it the idea behind labels inside tuples?
> > 
> > `foo(test1)` should raise an error `cannot convert value of type '(Int, Int)' to expected argument type '(a: Int, b: Int)'` as long as `test1` is not written like `let test1 = (a: 10, b: 100)` or `let test1: (a: Int, b: Int) = (a: 10, b: 100)`
> > 
> > This will impact current codebase if you used labels but provided tuples without labels like the example above. The migrator could solve this by providing labels automatically to tuples where this error occurs.
> > 
> > I'm not good at writing proposals for the GitHub repository at all, so if the community likes this idea, I'd be glad to see some help for this little proposal.
> > 
> > --  
> > Adrian Zubarev  
> > Sent with Airmail  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Lattner](https://forums.swift.org/u/Chris_Lattner)\
**Post date:** [April 20, 2016, 11:47pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/3 "2016-04-20T23:47:46Z")

</div>

> This is similar to another concern I raised with functions and being able to essentially erase the function argument names and apply two different named parameters just because their types match.
> 
> It seems reasonable to me that you can go from (x: Int, y: Int) =\> (Int, Int). However, going from (x: Int, y: Int) =\> (a: Int, b: Int) feels somewhat odd. Yes, the types can obviously slot in there fine, but how much importance do the labels for the types bring to the table?
> 
> Similarly, should this (Int, Int) =\> (x: Int, y: Int) be allowed through an implicit means? If so, then it's really just an intermediate step for (x: Int, y: Int) =\> (a: Int, b: Int) working.

I completely agree, I think it makes sense to convert from unlabeled to labeled (or back) but not from “labeled" to "differently labeled”.

> So what matters more, type signatures or label names?
> 
> Here's an example:
> 
> typealias Functor = (left: Int, right: Int) -\> Int
> 
> func hi(x: Int, y: Int, fn: Functor) -\> Int {  
> &nbsp;&nbsp;&nbsp;&nbsp;return fn(left: x, right: y)  
> }
> 
> hi(1, y: 2, fn: +)  
> hi(1, y: 2, fn: \*)
> 
> If we say that the parameter names are indeed vital, then the above code cannot work as the operators that match the type signature are defined as:
> 
> public func +(lhs: Int, rhs: Int) -\> Int
> 
> Obviously, given a name to the parameter brings clarity and can be self documenting, but if we want the above to work while making names just as vital as the type signature, then we need to declare `Functor` as such:
> 
> typealias Functor = (\_ left: Int, \_ right: Int) -\> Int
> 
> However, that's not even legal code today, and even if it were, is that really better?

I don’t think this follows, since operator parameters are always unlabeled. I suspect we don’t reject it, but I’d be in favor of rejecting:

func +(lhs xyz: Int, rhs abc: Int) -\> Int { }

-Chris

> **···**
>
> On Apr 20, 2016, at 12:31 PM, David Owens II via swift-evolution \<swift-evolution@swift.org\> wrote:

---

<div class="post-metadata">

**Author:** ![Haravikk3](https://avatars.discourse-cdn.com/v4/letter/h/df705f/32.png) [@Haravikk3](https://forums.swift.org/u/Haravikk3)\
**Post date:** [April 20, 2016, 6:10pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/4 "2016-04-20T18:10:55Z")

</div>

I’m not sure about a general rule, but I think that labels should be required for associated types and type aliases. I can’t check right now if this changed in Swift 3, but in earlier version Dictionary for example has the associated type Element which is a tuple of (Key, Value). While using this via .0 and .1 is fine generally, I’d much rather the parameters were named key and value for absolute clarity, and think that this the way to go with these. For ad-hoc tuples it doesn’t matter so much, but yeah, the rest of the time I’d prefer to be clear.

While it may be annoying in cases where names don’t match, I think that’s fine too, as it forces us to be explicit about what’s happening, as it may not always be clear to someone new to maintaining the code. There could perhaps be a simpler syntax for mapping tuples, or an attribute/compiler directive to ignore the mismatch anywhere it occurs?

> **···**
>
> > On 20 Apr 2016, at 14:23, Adrian Zubarev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I would like to discuss about the following topic.
> > 
> > Wouldn't it be better to enforce argument labels on tuples types, if the tuple type defines them?
> > 
> > ```swift
> > 
> > func foo(tuple: (a: Int, b: Int)) { /* do something */ }
> > 
> > let test1 = (10, 100)
> > let test2: (a: Int, c: Int) = test
> > let test3: (Int, Int) = test2
> > 
> > foo(test1)
> > foo(test3)
> > 
> > /*
> > cannot convert value of type '(a: Int, c: Int)' 
> > to expected argument type '(a: Int, b: Int)'
> > */
> > foo(test2) 
> > 
> > ```
> > 
> > Function `foo` awaits a tuple of type `(a: Int, b: Int)` but `test1` and `test3` are both just of type `(Int, Int)`.  
> > As expected `test2` will raise an error because it has indeed a wrong type `(a: Int, c: Int)`.
> > 
> > I'd suggest to enforce argument labeling on tuple types for better readability, because wasn't it the idea behind labels inside tuples?
> > 
> > `foo(test1)` should raise an error `cannot convert value of type '(Int, Int)' to expected argument type '(a: Int, b: Int)'` as long as `test1` is not written like `let test1 = (a: 10, b: 100)` or `let test1: (a: Int, b: Int) = (a: 10, b: 100)`
> > 
> > This will impact current codebase if you used labels but provided tuples without labels like the example above. The migrator could solve this by providing labels automatically to tuples where this error occurs.
> > 
> > I'm not good at writing proposals for the GitHub repository at all, so if the community likes this idea, I'd be glad to see some help for this little proposal.
> > 
> > --  
> > Adrian Zubarev  
> > Sent with Airmail  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [April 20, 2016, 5:47pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/5 "2016-04-20T17:47:00Z")

</div>

I think it's good that the labels aren't enforced:  
This would sacrifice flexibility, and force us to write unnecessary boilerplate to "translate" labels (one library might use (height, width), and another (h, w) to express the same concept…)

But: Objective-C had no tuples, so a final decision shouldn't happen until there is an agreement on best-practices for them...

---

<div class="post-metadata">

**Author:** ![Austin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/austin/32/1196_2.png) [@Austin](https://forums.swift.org/u/Austin)\
**Post date:** [April 20, 2016, 5:58pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/6 "2016-04-20T17:58:01Z")

</div>

+1 to Tino's concern. This seems like something better suited for a formal newtype style feature.

Austin

> **···**
>
> > On Apr 20, 2016, at 10:47 AM, Tino Heth via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I think it's good that the labels aren't enforced:  
> > This would sacrifice flexibility, and force us to write unnecessary boilerplate to "translate" labels (one library might use (height, width), and another (h, w) to express the same concept…)
> > 
> > But: Objective-C had no tuples, so a final decision shouldn't happen until there is an agreement on best-practices for them...  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![David\_Sweeris](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_sweeris/32/31302_2.png) [@David\_Sweeris](https://forums.swift.org/u/David_Sweeris)\
**Post date:** [April 20, 2016, 9:31pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/7 "2016-04-20T21:31:22Z")

</div>

What about enforcing the argument labels, but then adding a “@autolabel” or something in code where the current behavior is desired?

- Dave Sweeris

> **···**
>
> > On Apr 20, 2016, at 12:47 PM, Tino Heth via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I think it's good that the labels aren't enforced:  
> > This would sacrifice flexibility, and force us to write unnecessary boilerplate to "translate" labels (one library might use (height, width), and another (h, w) to express the same concept…)
> > 
> > But: Objective-C had no tuples, so a final decision shouldn't happen until there is an agreement on best-practices for them...  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 20, 2016, 5:59pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/8 "2016-04-20T17:59:22Z")

</div>

That’s why I’d like to discuss this topic and hear all your feedback.

Do you think it might be possible to add some optional extra flag to the language to enforce argument labeling. Not only for tuples as I started the discussion with but also for argument labels on blocks/closures?

```swift

@require_argument_label
func foo(tuple: (a: Int, b: Int)) { /* do some work */ }

// this will only work with

let test1 = (a: 1, b: 2)
foo(test1)

func foo(block: (boo: Int) -> Void) { /* pass boo to block */ }

foo() { boo in // do is enforced here
	/* do some work*/
}

// or

foo() { (boo: Int) -> Void in
	/* do some work*/
}

```

An extra flag won’t break any codebase and as an addition will allow some good looking syntax at some places.

> **···**
>
> --  
> Adrian Zubarev
> 
> Am 20. April 2016 bei 19:47:03, Tino Heth (2th@gmx.de) schrieb:
> 
> I think it's good that the labels aren't enforced:  
> This would sacrifice flexibility, and force us to write unnecessary boilerplate to "translate" labels (one library might use (height, width), and another (h, w) to express the same concept…)
> 
> But: Objective-C had no tuples, so a final decision shouldn't happen until there is an agreement on best-practices for them...

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 20, 2016, 6:24pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/9 "2016-04-20T18:24:06Z")

</div>

@Austin I wasn’t talking about the tuple splat feature here.

In my case I was trying to simplify the example of a function that awaits an actual tuple of a specific type, which in my case also (should) have argument labels.

```swift

func foo(tuple: (a: Int, b: Int)) {}

let tuple = (10, 42)
foo(tuple)

// this is not the same as 

func boo(a: Int, b: Int) {}
boo(42, b: 17)

let x = (1, b: 2)
boo(x) // which will be removed in Swift 3

```

> **···**
>
> --  
> Adrian Zubarev
> 
> Am 20. April 2016 bei 20:11:01, Haravikk (swift-evolution@haravikk.me) schrieb:
> 
> organization's policy

---

<div class="post-metadata">

**Author:** ![owensd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/owensd/32/8934_2.png) [@owensd](https://forums.swift.org/u/owensd)\
**Post date:** [April 21, 2016, 5:18am UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/10 "2016-04-21T05:18:38Z")

</div>

So maybe I think about this incorrectly, but I always think of any parameter without an explicit label to have one that is equal to the parameter name. So these two functions signatures would be equivalent:

func sum1(lhs: Int, rhs: Int) -\> Int  
func sum2(lhs lhs: Int, rhs rhs: Int) -\> Int

It’s only when you explicit “erase” the label where there is none:

func sum(\_ lhs: Int, \_ rhs: Int) -\> Int

So back to the example above, it’s still somewhat odd that all of these are valid:

hi(1, y: 2, fn: sum1)  
hi(1, y: 2, fn: sum2)  
hi(1, y: 2, fn: sum) // makes the most sense, no label to labeled promotion

But if we did reject the differently labeled version, that would mean that we would need to declare the `Functor` above as:

typealias Functor = (Int, Int) -\> Int

Is that better? I’m not terribly convinced that it is.

If `Functor` keeps the labels, I suspect it would just lead to additional boiler-plate code that would look like:

typealias Functor = (left: Int, right: Int) -\> Int

hi(1, y: 2, fn: { left, right in sum1(lhs: left, rhs: right) })

While it does seem technically correct, is that really the kind of code we want in Swift?

-David

> **···**
>
> > On Apr 20, 2016, at 4:47 PM, Chris Lattner \<clattner@apple.com\> wrote:
> > 
> > On Apr 20, 2016, at 12:31 PM, David Owens II via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > 
> > > This is similar to another concern I raised with functions and being able to essentially erase the function argument names and apply two different named parameters just because their types match.
> > > 
> > > It seems reasonable to me that you can go from (x: Int, y: Int) =\> (Int, Int). However, going from (x: Int, y: Int) =\> (a: Int, b: Int) feels somewhat odd. Yes, the types can obviously slot in there fine, but how much importance do the labels for the types bring to the table?
> > > 
> > > Similarly, should this (Int, Int) =\> (x: Int, y: Int) be allowed through an implicit means? If so, then it's really just an intermediate step for (x: Int, y: Int) =\> (a: Int, b: Int) working.
> > 
> > I completely agree, I think it makes sense to convert from unlabeled to labeled (or back) but not from “labeled" to "differently labeled”.
> > 
> > > So what matters more, type signatures or label names?
> > > 
> > > Here's an example:
> > > 
> > > typealias Functor = (left: Int, right: Int) -\> Int
> > > 
> > > func hi(x: Int, y: Int, fn: Functor) -\> Int {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return fn(left: x, right: y)  
> > > }
> > > 
> > > hi(1, y: 2, fn: +)  
> > > hi(1, y: 2, fn: \*)
> > > 
> > > If we say that the parameter names are indeed vital, then the above code cannot work as the operators that match the type signature are defined as:
> > > 
> > > public func +(lhs: Int, rhs: Int) -\> Int
> > > 
> > > Obviously, given a name to the parameter brings clarity and can be self documenting, but if we want the above to work while making names just as vital as the type signature, then we need to declare `Functor` as such:
> > > 
> > > typealias Functor = (\_ left: Int, \_ right: Int) -\> Int
> > > 
> > > However, that's not even legal code today, and even if it were, is that really better?
> > 
> > I don’t think this follows, since operator parameters are always unlabeled. I suspect we don’t reject it, but I’d be in favor of rejecting:
> > 
> > func +(lhs xyz: Int, rhs abc: Int) -\> Int { }

---

<div class="post-metadata">

**Author:** ![William\_Dillon2](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/william_dillon2/32/297_2.png) [@William\_Dillon2](https://forums.swift.org/u/William_Dillon2)\
**Post date:** [April 20, 2016, 6:03pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/11 "2016-04-20T18:03:15Z")

</div>

> Do you think it might be possible to add some optional extra flag to the language to enforce argument labeling. Not only for tuples as I started the discussion with but also for argument labels on blocks/closures?

That seems fairly heavy-handed, also.

This feels like the kind of thing that should be enforced by an organization's policy not by the language, IMHO.

- Will

---

<div class="post-metadata">

**Author:** ![Austin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/austin/32/1196_2.png) [@Austin](https://forums.swift.org/u/Austin)\
**Post date:** [April 20, 2016, 6:08pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/12 "2016-04-20T18:08:22Z")

</div>

The tuple splat feature you mention below ("foo(test1)", where test1 is a tuple ) is going away in Swift 3, as is the entire idea of modeling a function's list of formal parameters as a named tuple.

Aside from that, my personal opinion is that forcing a closure to take certain argument names is way too onerous a requirement for very little benefit. It would, for example, disqualify the use of the $x wildcards or the use of local argument names which more precisely represent the semantics of the closure. Function signatures are already very complicated, so I think any new attributes or flags should really have a strong argument to justify their inclusion.

Austin

> **···**
>
> > On Apr 20, 2016, at 10:59 AM, Adrian Zubarev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > That’s why I’d like to discuss this topic and hear all your feedback.
> > 
> > Do you think it might be possible to add some optional extra flag to the language to enforce argument labeling. Not only for tuples as I started the discussion with but also for argument labels on blocks/closures?
> > 
> > ```swift
> > 
> > @require_argument_label
> > func foo(tuple: (a: Int, b: Int)) { /* do some work */ }
> > 
> > // this will only work with
> > 
> > let test1 = (a: 1, b: 2)
> > foo(test1)
> > 
> > func foo(block: (boo: Int) -> Void) { /* pass boo to block */ }
> > 
> > foo() { boo in // do is enforced here
> > /* do some work*/
> > }
> > 
> > // or
> > 
> > foo() { (boo: Int) -> Void in
> > /* do some work*/
> > }
> > 
> > ```
> > 
> > An extra flag won’t break any codebase and as an addition will allow some good looking syntax at some places.
> > 
> > --  
> > Adrian Zubarev
> > 
> > Am 20. April 2016 bei 19:47:03, Tino Heth (2th@gmx.de \<mailto:2th@gmx.de\>) schrieb:
> > 
> > > I think it's good that the labels aren't enforced:  
> > > This would sacrifice flexibility, and force us to write unnecessary boilerplate to "translate" labels (one library might use (height, width), and another (h, w) to express the same concept…)
> > > 
> > > But: Objective-C had no tuples, so a final decision shouldn't happen until there is an agreement on best-practices for them...
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 20, 2016, 6:01pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/13 "2016-04-20T18:01:23Z")

</div>

I forgot something in my previous post:

```swift

@require_argument_label
func foo(block: (boo: Int) -> Void) { /* pass boo to block */ }

foo() { boo in // do is enforced here
	/* do some work*/
}

```

> **···**
>
> --  
> Adrian Zubarev
> 
> Am 20. April 2016 bei 19:59:23, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:
> 
> @require\_argument\_label

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [April 20, 2016, 7:21pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/14 "2016-04-20T19:21:24Z")

</div>

> Do you think it might be possible to add some optional extra flag to the language to enforce argument labeling. Not only for tuples as I started the discussion with but also for argument labels on blocks/closures?

I'm quite skeptical when it comes to enforce behavior (unless it's the way I prefer it anyways ;-) — and in this case, I think the carrot is better than the stick:  
Leave the language as it is, but let the tools add the "right" labels by default (sadly, there is no thing like Xcode-evolution… ;-)

---

<div class="post-metadata">

**Author:** ![Haravikk3](https://avatars.discourse-cdn.com/v4/letter/h/df705f/32.png) [@Haravikk3](https://forums.swift.org/u/Haravikk3)\
**Post date:** [April 21, 2016, 7:14am UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/15 "2016-04-21T07:14:01Z")

</div>

I think the important thing to remember is that the label check is intended to prevent cases like this:

&nbsp;&nbsp;let a:(left:Int, right:Int) = (1, 2)  
&nbsp;&nbsp;var b:(right:Int, left:Int) = a

While the two tuples are compatible by type, the meaning of the values may differ due to the different labels; in this case the values are represented in a different order that a developer should have to explicitly reverse to ensure they aren’t making a mistake, or they could represent radically different concepts altogether.

It’s certainly annoying when the labels are only different due to minor differences, but the compiler doesn’t know that. So yeah, I think that in any case where there are external labels that differ a warning should be raised; this comes down to being able to later ignore types of warnings, which could avoid the boiler-plate in future.

The alternative would be if we had some syntax for mapping parameters more cleanly, for example:

&nbsp;&nbsp;hi(1, y: 2, fn: sum1 where left = lhs, right = rhs)

Or something along those lines anyway?

> **···**
>
> > On 21 Apr 2016, at 06:18, David Owens II via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > > On Apr 20, 2016, at 4:47 PM, Chris Lattner \<clattner@apple.com \<mailto:clattner@apple.com\>\> wrote:
> > > 
> > > On Apr 20, 2016, at 12:31 PM, David Owens II via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > > This is similar to another concern I raised with functions and being able to essentially erase the function argument names and apply two different named parameters just because their types match.
> > > > 
> > > > It seems reasonable to me that you can go from (x: Int, y: Int) =\> (Int, Int). However, going from (x: Int, y: Int) =\> (a: Int, b: Int) feels somewhat odd. Yes, the types can obviously slot in there fine, but how much importance do the labels for the types bring to the table?
> > > > 
> > > > Similarly, should this (Int, Int) =\> (x: Int, y: Int) be allowed through an implicit means? If so, then it's really just an intermediate step for (x: Int, y: Int) =\> (a: Int, b: Int) working.
> > > 
> > > I completely agree, I think it makes sense to convert from unlabeled to labeled (or back) but not from “labeled" to "differently labeled”.
> > > 
> > > > So what matters more, type signatures or label names?
> > > > 
> > > > Here's an example:
> > > > 
> > > > typealias Functor = (left: Int, right: Int) -\> Int
> > > > 
> > > > func hi(x: Int, y: Int, fn: Functor) -\> Int {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;return fn(left: x, right: y)  
> > > > }
> > > > 
> > > > hi(1, y: 2, fn: +)  
> > > > hi(1, y: 2, fn: \*)
> > > > 
> > > > If we say that the parameter names are indeed vital, then the above code cannot work as the operators that match the type signature are defined as:
> > > > 
> > > > public func +(lhs: Int, rhs: Int) -\> Int
> > > > 
> > > > Obviously, given a name to the parameter brings clarity and can be self documenting, but if we want the above to work while making names just as vital as the type signature, then we need to declare `Functor` as such:
> > > > 
> > > > typealias Functor = (\_ left: Int, \_ right: Int) -\> Int
> > > > 
> > > > However, that's not even legal code today, and even if it were, is that really better?
> > > 
> > > I don’t think this follows, since operator parameters are always unlabeled. I suspect we don’t reject it, but I’d be in favor of rejecting:
> > > 
> > > func +(lhs xyz: Int, rhs abc: Int) -\> Int { }
> > 
> > So maybe I think about this incorrectly, but I always think of any parameter without an explicit label to have one that is equal to the parameter name. So these two functions signatures would be equivalent:
> > 
> > func sum1(lhs: Int, rhs: Int) -\> Int  
> > func sum2(lhs lhs: Int, rhs rhs: Int) -\> Int
> > 
> > It’s only when you explicit “erase” the label where there is none:
> > 
> > func sum(\_ lhs: Int, \_ rhs: Int) -\> Int
> > 
> > So back to the example above, it’s still somewhat odd that all of these are valid:
> > 
> > hi(1, y: 2, fn: sum1)  
> > hi(1, y: 2, fn: sum2)  
> > hi(1, y: 2, fn: sum) // makes the most sense, no label to labeled promotion
> > 
> > But if we did reject the differently labeled version, that would mean that we would need to declare the `Functor` above as:
> > 
> > typealias Functor = (Int, Int) -\> Int
> > 
> > Is that better? I’m not terribly convinced that it is.
> > 
> > If `Functor` keeps the labels, I suspect it would just lead to additional boiler-plate code that would look like:
> > 
> > typealias Functor = (left: Int, right: Int) -\> Int
> > 
> > hi(1, y: 2, fn: { left, right in sum1(lhs: left, rhs: right) })
> > 
> > While it does seem technically correct, is that really the kind of code we want in Swift?
> > 
> > -David  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Lattner](https://forums.swift.org/u/Chris_Lattner)\
**Post date:** [April 24, 2016, 9:52pm UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/16 "2016-04-24T21:52:17Z")

</div>

> > > Obviously, given a name to the parameter brings clarity and can be self documenting, but if we want the above to work while making names just as vital as the type signature, then we need to declare `Functor` as such:
> > > 
> > > typealias Functor = (\_ left: Int, \_ right: Int) -\> Int
> > > 
> > > However, that's not even legal code today, and even if it were, is that really better?
> > 
> > I don’t think this follows, since operator parameters are always unlabeled. I suspect we don’t reject it, but I’d be in favor of rejecting:
> > 
> > func +(lhs xyz: Int, rhs abc: Int) -\> Int { }
> 
> So maybe I think about this incorrectly, but I always think of any parameter without an explicit label to have one that is equal to the parameter name.

We’re going in that direction, but that is not currently the case for operators and subscript indices. As a community, we don’t have much real-world experience using Swift 3, but I don’t expect that either of those cases would get better by requiring labels by default and requiring \_ to suppress them.

> So these two functions signatures would be equivalent:
> 
> func sum1(lhs: Int, rhs: Int) -\> Int  
> func sum2(lhs lhs: Int, rhs rhs: Int) -\> Int
> 
> It’s only when you explicit “erase” the label where there is none:
> 
> func sum(\_ lhs: Int, \_ rhs: Int) -\> Int
> 
> So back to the example above, it’s still somewhat odd that all of these are valid:
> 
> hi(1, y: 2, fn: sum1)  
> hi(1, y: 2, fn: sum2)  
> hi(1, y: 2, fn: sum) // makes the most sense, no label to labeled promotion
> 
> But if we did reject the differently labeled version, that would mean that we would need to declare the `Functor` above as:
> 
> typealias Functor = (Int, Int) -\> Int

I agree that eliminating relabeling would force this.

> Is that better? I’m not terribly convinced that it is.

Me neither.

Off in crazy space for a bit, but one could argue that this style of design would imply that you should be able to call this example like this:

> hi(1, y: 2, fn: { sum1(lhs: $left, rhs: $right) })

since the only sensible names for the parameters come from context.

-Chris

> **···**
>
> On Apr 20, 2016, at 10:18 PM, David Owens II \<david@owensd.io\> wrote:

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 21, 2016, 9:14am UTC](https://forums.swift.org/t/discussion-enforce-argument-labels-on-tuples/2273/17 "2016-04-21T09:14:07Z")

</div>

Personally I'm fine with the way it is right now, but I do miss enforced labels at some point. At least it would be 'nice to have' feature like we already have @autoclosure or @noescape to enforce some specific behaviour.

I started the discussion about enforcing argument labels on tuples but with your feedback I totally see the point why this shouldn’t be something backed inside the language by default.

Optional way to enforce the usage of correct/strict/explicit labels could provide better readability from my point of view.

Remember the idea of cascading methods/initializer? For class types it’s almost possible to build that feature by yourself, but there is one problem that was discussed back then. What do we use inside the trailing closure to access the instance.  
Sure we could give it a custom name or just use `$0`.

```swift
let instance = ClassA() {

      // customName in
      // or $0
}

// imagine we had something optional like
class ClassB {

      @require_explicit_label_usage
      init(closure: (this: ClassB) -> Void) {

            closure(this: self)
      }
      func foo() {}
}

// now we could use it like

let b = ClassB() { this in // can be omitted due the use of @require_explicit_label_usage

       this.foo()
}

// I'll use ++ operator just for the example here

@require_explicit_label_usage
prefix func ++ (tuple: (exp: Int, earned: Int)) -> Int {

     return tuple.apples + tuple.amount
}

// this operator will only overload when the right labeling is applied to the tuple

++(exp: 10, earned: 5) // result would be 15

// the operator wont work with
++(100, 50)
// give another dev this snippet and ask him what 100 and 50 means

```

This example is very abstract but I'm sure you should get the point of the possible need of an optional label enforcement.

By the way, why does Swift allow something like this anyway?

var a = (a: 10) // is of type Int

Where something like the next example is not allowed at all:

var a: (a: Int) = (a: 10)

> **···**
>
> --  
> Adrian Zubarev
> 
> Am 21. April 2016 bei 09:14:16, Haravikk via swift-evolution (swift-evolution@swift.org) schrieb:
> 
> I think the important thing to remember is that the label check is intended to prevent cases like this:
> 
> let a:(left:Int, right:Int) = (1, 2)  
> var b:(right:Int, left:Int) = a
> 
> While the two tuples are compatible by type, the meaning of the values may differ due to the different labels; in this case the values are represented in a different order that a developer should have to explicitly reverse to ensure they aren’t making a mistake, or they could represent radically different concepts altogether.
> 
> It’s certainly annoying when the labels are only different due to minor differences, but the compiler doesn’t know that. So yeah, I think that in any case where there are external labels that differ a warning should be raised; this comes down to being able to later ignore types of warnings, which could avoid the boiler-plate in future.
> 
> The alternative would be if we had some syntax for mapping parameters more cleanly, for example:
> 
> hi(1, y: 2, fn: sum1 where left = lhs, right = rhs)
> 
> Or something along those lines anyway?
> 
> On 21 Apr 2016, at 06:18, David Owens II via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> On Apr 20, 2016, at 4:47 PM, Chris Lattner \<clattner@apple.com\> wrote:
> 
> On Apr 20, 2016, at 12:31 PM, David Owens II via swift-evolution \<swift-evolution@swift.org\> wrote:  
> This is similar to another concern I raised with functions and being able to essentially erase the function argument names and apply two different named parameters just because their types match.
> 
> It seems reasonable to me that you can go from (x: Int, y: Int) =\> (Int, Int). However, going from (x: Int, y: Int) =\> (a: Int, b: Int) feels somewhat odd. Yes, the types can obviously slot in there fine, but how much importance do the labels for the types bring to the table?
> 
> Similarly, should this (Int, Int) =\> (x: Int, y: Int) be allowed through an implicit means? If so, then it's really just an intermediate step for (x: Int, y: Int) =\> (a: Int, b: Int) working.
> 
> I completely agree, I think it makes sense to convert from unlabeled to labeled (or back) but not from “labeled" to "differently labeled”.
> 
> So what matters more, type signatures or label names?
> 
> Here's an example:
> 
> typealias Functor = (left: Int, right: Int) -\> Int
> 
> func hi(x: Int, y: Int, fn: Functor) -\> Int {  
> return fn(left: x, right: y)  
> }
> 
> hi(1, y: 2, fn: +)  
> hi(1, y: 2, fn: \*)
> 
> If we say that the parameter names are indeed vital, then the above code cannot work as the operators that match the type signature are defined as:
> 
> public func +(lhs: Int, rhs: Int) -\> Int
> 
> Obviously, given a name to the parameter brings clarity and can be self documenting, but if we want the above to work while making names just as vital as the type signature, then we need to declare `Functor` as such:
> 
> typealias Functor = (\_ left: Int, \_ right: Int) -\> Int
> 
> However, that's not even legal code today, and even if it were, is that really better?
> 
> I don’t think this follows, since operator parameters are always unlabeled. I suspect we don’t reject it, but I’d be in favor of rejecting:
> 
> func +(lhs xyz: Int, rhs abc: Int) -\> Int { }
> 
> So maybe I think about this incorrectly, but I always think of any parameter without an explicit label to have one that is equal to the parameter name. So these two functions signatures would be equivalent:
> 
> func sum1(lhs: Int, rhs: Int) -\> Int  
> func sum2(lhs lhs: Int, rhs rhs: Int) -\> Int
> 
> It’s only when you explicit “erase” the label where there is none:
> 
> func sum(\_ lhs: Int, \_ rhs: Int) -\> Int
> 
> So back to the example above, it’s still somewhat odd that all of these are valid:
> 
> hi(1, y: 2, fn: sum1)  
> hi(1, y: 2, fn: sum2)  
> hi(1, y: 2, fn: sum) // makes the most sense, no label to labeled promotion
> 
> But if we did reject the differently labeled version, that would mean that we would need to declare the `Functor` above as:
> 
> typealias Functor = (Int, Int) -\> Int
> 
> Is that better? I’m not terribly convinced that it is.
> 
> If `Functor` keeps the labels, I suspect it would just lead to additional boiler-plate code that would look like:
> 
> typealias Functor = (left: Int, right: Int) -\> Int
> 
> hi(1, y: 2, fn: { left, right in sum1(lhs: left, rhs: right) })
> 
> While it does seem technically correct, is that really the kind of code we want in Swift?
> 
> -David  
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> swift-evolution mailing list  
> swift-evolution@swift.org  
> [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> 
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> swift-evolution mailing list  
> swift-evolution@swift.org  
> [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
