[Pitch] Make the first parameter in a function declaration follow the same rules as the others

You say it like it is a bad thing :P.

+1 to argument labels. The thing I dislike the most in C/C++/Java... The lack of them :).

···

Sent from my iPhone

On 9 Mar 2016, at 19:04, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

+1.

Swift is not Objective-C.

-- E

On Mar 9, 2016, at 11:58 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1

···

On Wed, Mar 9, 2016 at 8:04 PM, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

+1.

Swift is not Objective-C.

-- E

On Mar 9, 2016, at 11:58 AM, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote:

Our accepted naming guidelines have embraced first argument labels for
functions and methods. This weakens our justification for making the first
parameter declaration in a `func` declaration behave differently from the
others, implicitly being unlabeled. It seems pretty clear to me we should
make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently,
which is nice. There may still be hope for our keyword argument rules to
one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
bitCycle AB | Smedjegatan 12 | 742 32 Östhammar | Sweden

Phone: +46-73-753 24 62
E-mail: jens@bitcycle.com

+1

P.S. During my Swift tutoring lessons, the current behavior confuses everybody to no end.

…are we sure this isn’t just because people are just down right daft at times. I would in no way consider the Swift 2 syntax confusing. It’s ugly (compared to the proposed 'func foo(x: Int, y: Int)') and frustrating to be sure, but not confusing. Like all students learning something, sometimes one just have to take something at face value—it is what it is and that’s life, haha. Sometimes I really find myself wondering if anyone has ever read “The Swift Programming Language” text. It always seems like people spend more time just “playing around" with Swift—learning by trial and error. That’s a bad idea for learning anything as experimenting and understanding what the result requires knowing something in the first place.

No offense, but if people would spend more time learning the language instead of comparing it to other languages while they learn it, they may not have such problems. Perhaps even a good number of the arguments put forth on these threads may not come up either… food for thought.

I’m definitely +1 on making ‘func' and and ‘init' have the same type of argument signature.

    func foo(x: Int, y: Int) // Looks so much BETTER!!!!

Myles

···

On Mar 9, 2016, at 5:24 PM, Rudolf Adamkovič via swift-evolution <swift-evolution@swift.org> wrote:

R+

On 9 Mar 2016, at 19:58, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1

···

On 10 Mar 2016, at 02:02, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Mar 9, 2016, at 11:58 AM, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe

tweet: http://twitter.com/jckarter/status/707691862836924416
gist: firstlabel.md · GitHub
Pull request: Establish consistent label behavior across all parameters by erica · Pull Request #200 · apple/swift-evolution · GitHub

Establish consistent label behavior across all parameters including first labels

Proposal: TBD
Author(s): Joe Groff <http://github.com/jckarter&gt;, Jake Carter <https://github.com/JakeCarter&gt;, Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<firstlabel.md · GitHub

We propose to normalize the first parameter declaration in methods and functions. In this proposal, first parameter declarations will match the existing behavior of the second and later parameters. All parameters, regardless of position, will behave uniformly. This will create a simple, consistent approach to parameter declaration throughout the Swift programming language and bring method and function declarations in-sync with initalizers, which already use this standard.

Discussion took place on the Swift Evolution mailing list in the Make the first parameter in a function declaration follow the same rules as the others <http://article.gmane.org/gmane.comp.lang.swift.evolution/9029&gt; thread.

<firstlabel.md · GitHub

In the current state of the art, Swift 2 methods and functions combine local and external names to label parameters. These differentiated symbols distinguish names for internal implementation and external consumption. By default, a Swift 2 parameter declaration that appears first in the parameter list omits its external name. Second and later parameters duplicate local names as external labels. Under these Swift 2 rules, a declaration that looks like this:

func foo(a: T, b: U, c: V)
declares foo(_:b:c:) and not foo(a:b:c).

Historically, this label behavior was normalized in Swift 2, unifying parameter naming rules for methods and functions, which had previously used separate defaults behaviors. The new unified approach approximated Objective-C naming conventions where first parameter labels were subsumed into the first part of a method signature. For the most part, Swift 2 developers were encouraged to mimic this approach and build calls that moved the label name out of the parameter list and into the function or method name.

Swift 3's newly accepted API naming guidelines <https://swift.org/documentation/api-design-guidelines/&gt; shook up this approach. They more thoroughly embraced method and function first argument labels. The updated naming guidance is further supported by the automated Objective-C API translation rules <https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md&gt; recently accepted for Swift 3. Under these revised guidelines, first argument labels are encouraged for but are not limited to:

methods and functions where the first parameter of a method is defaulted
methods and functions where the first argument uses a prepositional phrase
methods and functions that implement factory methods
methods and functions where method arguments represent a split form of a single abstraction
First argument labels are also the standard for initializers.

This expanded guidance creates a greater reach of first argument label usage and weakens justification for a first-parameter exception. Ensuring that parameter declarations behave uniformly supports Swift's goals of clarity and consistency. This change produces the simplest and most predictable usage, simplifying naming tasks, reducing confusion, and easing transition to the language.

<firstlabel.md · GitHub Design

Under this proposal, first parameters names automatically create matching external labels, mimicking the second and later parameters. For example

func foo(x: Int, y: Int)
will declare foo(x:y:) and not foo(_:,y:). Developers will no longer need to double the first label to expose it to consuming API calls.

The existing external label overrides will continue to apply to first parameters. You establish external parameter names before the local parameter name it supports, separated by a space. For example,

func foo(xx x: Int, yy y: Int)
declares foo(xx:yy:) and

func foo(_ x: Int, y: Int)
explicitly declares foo(_:y:)

<firstlabel.md · GitHub on Existing Code

This proposal will impact existing code, requiring migration support from Xcode. We propose the following solution:

Function declarations that do not include explicit first item external labels (for example, func foo(x: Int, y: Int)) will translate to func foo(_ x: Int, y: Int).
Function call sites (e.g. foo(2, y: 3)) will remain unaffected.
Alternatively, this fixit behavior can be swapped. The callsite can update (foo(x:2, y:3)) and the declaration left as is. We feel the latter approach has a greater impact on existing code as functions are more often called than declared.

Ideally the migrator will locate patterns where the last letters of a function name match the first parameter name, for example tintWithColor(color: UIColor), and insert a FIXME: warning suggesting manual migration. Swift's automatic Objective-C import code might be repurposed to detect a prepositional phrase and parameter match to automate a fixit for tint(color: UIColor) but this would involve a more complicated implementation.

<firstlabel.md · GitHub Considered

There are no alternatives considered at this time.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Big +1 too.

Pierre

···

Le 10 mars 2016 à 11:07, Adrian Kashivskyy via swift-evolution <swift-evolution@swift.org> a écrit :

Big +1

Pozdrawiam – Regards,
Adrian Kashivskyy

Wiadomość napisana przez Joe Groff via swift-evolution <swift-evolution@swift.org> w dniu 09.03.2016, o godz. 19:58:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

This is a valid concern.

If we assumed that 50% of methods would have a labelled first parameter, and 50% would leave them unlabelled, and furthermore we assume that all methods with labelled first parameters would use the parameter name as the label, then I would support this proposal purely on the grounds that it's easier to write `func foo(_ bar: T)` than it is to write `func foo(bar bar: T)`.

However, if we assume that the majority of methods still want an
unlabelled first parameter (which seems like a reasonable assumption to
me; most of the methods I write would certainly have the first parameter
unlabelled), and similarly if we assume that a non-trivial amount of
labelled first parameters use a different label than the parameter name,
then this change doesn't make as much sense anymore.

Another concern with this proposal is that, even if you assume most
methods with multiple parameters would want to label all the parameters,
it's likely that most methods with a single parameter will leave the
parameter unlabelled. But this proposed rule would cause even single-
argument methods to label the sole argument.

-Kevin Ballard

···

On Wed, Mar 9, 2016, at 05:03 PM, Jordan Rose via swift-evolution wrote:

This is my concern too. Our guidelines often lead to the first
parameter having a label, but usually that name isn't the same as the
name of the parameter—one's a preposition, the other's a noun. I'm
pretty sure the common case is still unlabeled. Does that justify the
complexity of the current rule?

(But because Objective-C methods will now often have labeled
arguments, it would at least no longer be a marker differentiating
"pure Swift" code from "Cocoa" code.)

Jordan

On Mar 9, 2016, at 14:32, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

Looking at my code, the majority of methods should still have the
first parameter unlabeled.

I like the consistency of what you’re proposing and the fact that I don’t have to write `func foo(someArgument someArgument: T)` anymore. But I also fear people won’t get it that they can (and in many, probably most, situations should) make the first parameter `_ foo`.

— Radek

On 09 Mar 2016, at 19:58, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave
consistently, which is nice. There may still be hope for our keyword
argument rules to one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_________________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

This is my concern too. Our guidelines often lead to the first
parameter having a label, but usually that name isn't the same as the
name of the parameter—one's a preposition, the other's a noun. I'm
pretty sure the common case is still unlabeled.

It's about 50/50 (slight edge to labeled first parameters) in the
imported Cocoa APIs.

···

on Wed Mar 09 2016, Jordan Rose <swift-evolution@swift.org> wrote:

Does that justify the complexity of the current rule?

(But because Objective-C methods will now often have labeled
arguments, it would at least no longer be a marker differentiating
"pure Swift" code from "Cocoa" code.)

Jordan

On Mar 9, 2016, at 14:32, Radosław Pietruszewski via swift-evolution >> <swift-evolution@swift.org> wrote:

Looking at my code, the majority of methods should still have the first parameter unlabeled.

I like the consistency of what you’re proposing and the fact that I
don’t have to write `func foo(someArgument someArgument: T)`
anymore. But I also fear people won’t get it that they can (and in
many, probably most, situations should) make the first parameter `_
foo`.

— Radek

On 09 Mar 2016, at 19:58, Joe Groff via swift-evolution >>> <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> >>> wrote:

Our accepted naming guidelines have embraced first argument labels
for functions and methods. This weakens our justification for
making the first parameter declaration in a `func` declaration
behave differently from the others, implicitly being unlabeled. It
seems pretty clear to me we should make all of the parameter
declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave
consistently, which is nice. There may still be hope for our
keyword argument rules to one day be shorter than the Smalltalk
spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

I would agree that in following the Swift.org API Design Guidelines I've had to do a lot of `func foo(x x: Type)`.

But simple functions like `.remove(element)` or `.append(element)`
that really don't need labels are ubiquitous and would need to be
changed to `_ x:`.

I assume the goal is to have the default case be whatever developers
will use most commonly.

Actually, having the default case be the one that's most predictable and
easiest to use has a lot of merit. I can't tell you the number of times
where I've seen someone write

      func f(a: B, c: D)

when they've really meant

      func f(a _: B, c: D)

because the first argument is treated differently.

If you want to have some fun, though, count the ratio of APIs with first
argument labels to APIs without them in the proposed SDK revisions ;-)

···

on Wed Mar 09 2016, Tanner Nelson <swift-evolution@swift.org> wrote:

On Mar 9, 2016, at 3:15 PM, Jose Cheyo Jimenez via swift-evolution >> <swift-evolution@swift.org> wrote:

+1 Yes

the current solution makes me wish we still have the # from swift 1 ;)

  func foo(x x: Int, y: Int) // Swift 2
  func foo(#x: Int, y: Int) // Swift 1

On Mar 9, 2016, at 10:58 AM, Joe Groff via swift-evolution >>> <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> >>> wrote:

Our accepted naming guidelines have embraced first argument labels
for functions and methods. This weakens our justification for
making the first parameter declaration in a `func` declaration
behave differently from the others, implicitly being unlabeled. It
seems pretty clear to me we should make all of the parameter
declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave
consistently, which is nice. There may still be hope for our
keyword argument rules to one day be shorter than the Smalltalk
spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

I actually thought that this change was implied with the new guidelines.

Félix

···

Le 9 mars 2016 à 15:35:12, Tanner Nelson via swift-evolution <swift-evolution@swift.org> a écrit :

I would agree that in following the Swift.org <http://swift.org/&gt; API Design Guidelines I've had to do a lot of `func foo(x x: Type)`.

But simple functions like `.remove(element)` or `.append(element)` that really don't need labels are ubiquitous and would need to be changed to `_ x:`.

I assume the goal is to have the default case be whatever developers will use most commonly.

On Mar 9, 2016, at 3:15 PM, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

+1 Yes

the current solution makes me wish we still have the # from swift 1 ;)

  func foo(x x: Int, y: Int) // Swift 2
  func foo(#x: Int, y: Int) // Swift 1

On Mar 9, 2016, at 10:58 AM, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1. Because I’m old and slow, it took a long time to not get an eyeball jolt upon seeing foo(_:y:). Thank you.

···

On Mar 10, 2016, at 1:20 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

+1

On 10 Mar 2016, at 02:02, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 9, 2016, at 11:58 AM, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe

tweet: http://twitter.com/jckarter/status/707691862836924416
gist: firstlabel.md · GitHub
Pull request: Establish consistent label behavior across all parameters by erica · Pull Request #200 · apple/swift-evolution · GitHub

Establish consistent label behavior across all parameters including first labels

Proposal: TBD
Author(s): Joe Groff <http://github.com/jckarter&gt;, Jake Carter <https://github.com/JakeCarter&gt;, Erica Sadun <http://github.com/erica&gt;
Status: TBD
Review manager: TBD
<firstlabel.md · GitHub

We propose to normalize the first parameter declaration in methods and functions. In this proposal, first parameter declarations will match the existing behavior of the second and later parameters. All parameters, regardless of position, will behave uniformly. This will create a simple, consistent approach to parameter declaration throughout the Swift programming language and bring method and function declarations in-sync with initalizers, which already use this standard.

Discussion took place on the Swift Evolution mailing list in the Make the first parameter in a function declaration follow the same rules as the others <http://article.gmane.org/gmane.comp.lang.swift.evolution/9029&gt; thread.

<firstlabel.md · GitHub

In the current state of the art, Swift 2 methods and functions combine local and external names to label parameters. These differentiated symbols distinguish names for internal implementation and external consumption. By default, a Swift 2 parameter declaration that appears first in the parameter list omits its external name. Second and later parameters duplicate local names as external labels. Under these Swift 2 rules, a declaration that looks like this:

func foo(a: T, b: U, c: V)
declares foo(_:b:c:) and not foo(a:b:c).

Historically, this label behavior was normalized in Swift 2, unifying parameter naming rules for methods and functions, which had previously used separate defaults behaviors. The new unified approach approximated Objective-C naming conventions where first parameter labels were subsumed into the first part of a method signature. For the most part, Swift 2 developers were encouraged to mimic this approach and build calls that moved the label name out of the parameter list and into the function or method name.

Swift 3's newly accepted API naming guidelines <https://swift.org/documentation/api-design-guidelines/&gt; shook up this approach. They more thoroughly embraced method and function first argument labels. The updated naming guidance is further supported by the automated Objective-C API translation rules <https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md&gt; recently accepted for Swift 3. Under these revised guidelines, first argument labels are encouraged for but are not limited to:

methods and functions where the first parameter of a method is defaulted
methods and functions where the first argument uses a prepositional phrase
methods and functions that implement factory methods
methods and functions where method arguments represent a split form of a single abstraction
First argument labels are also the standard for initializers.

This expanded guidance creates a greater reach of first argument label usage and weakens justification for a first-parameter exception. Ensuring that parameter declarations behave uniformly supports Swift's goals of clarity and consistency. This change produces the simplest and most predictable usage, simplifying naming tasks, reducing confusion, and easing transition to the language.

<firstlabel.md · GitHub Design

Under this proposal, first parameters names automatically create matching external labels, mimicking the second and later parameters. For example

func foo(x: Int, y: Int)
will declare foo(x:y:) and not foo(_:,y:). Developers will no longer need to double the first label to expose it to consuming API calls.

The existing external label overrides will continue to apply to first parameters. You establish external parameter names before the local parameter name it supports, separated by a space. For example,

func foo(xx x: Int, yy y: Int)
declares foo(xx:yy:) and

func foo(_ x: Int, y: Int)
explicitly declares foo(_:y:)

<firstlabel.md · GitHub on Existing Code

This proposal will impact existing code, requiring migration support from Xcode. We propose the following solution:

Function declarations that do not include explicit first item external labels (for example, func foo(x: Int, y: Int)) will translate to func foo(_ x: Int, y: Int).
Function call sites (e.g. foo(2, y: 3)) will remain unaffected.
Alternatively, this fixit behavior can be swapped. The callsite can update (foo(x:2, y:3)) and the declaration left as is. We feel the latter approach has a greater impact on existing code as functions are more often called than declared.

Ideally the migrator will locate patterns where the last letters of a function name match the first parameter name, for example tintWithColor(color: UIColor), and insert a FIXME: warning suggesting manual migration. Swift's automatic Objective-C import code might be repurposed to detect a prepositional phrase and parameter match to automate a fixit for tint(color: UIColor) but this would involve a more complicated implementation.

<firstlabel.md · GitHub Considered

There are no alternatives considered at this time.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I’ve been thinking about this proposal, and don’t like it. I feel that it makes the language uglier, even if more consistent, and for a very common case.

But I do have one idea, which is to substitute a dot for the colon in the definition when no label is desired:

  func foo(x: Int, y: Int) // x is labeled
  func foo(x. Int, y: Int) // x is unlabeled
  func foo(x. Int, y. Int) // x and y are both unlabeled
  func foo(xx x. Int) // Illegal to label a parameter when using the “.” shortcut

This makes things consistent, and even sortof pretty. It also has a bit of a shorthand, since you’re leaving out one dot of the colon to make it silent (unlabeled). I have no idea how much his might mess up the rest of the grammar, but it seems like it might work.

James

···

On Mar 10, 2016, at 2:21 PM, Kevin Ballard via swift-evolution <swift-evolution@swift.org> wrote:

This is a valid concern.

If we assumed that 50% of methods would have a labelled first parameter, and 50% would leave them unlabelled, and furthermore we assume that all methods with labelled first parameters would use the parameter name as the label, then I would support this proposal purely on the grounds that it's easier to write `func foo(_ bar: T)` than it is to write `func foo(bar bar: T)`.

However, if we assume that the majority of methods still want an unlabelled first parameter (which seems like a reasonable assumption to me; most of the methods I write would certainly have the first parameter unlabelled), and similarly if we assume that a non-trivial amount of labelled first parameters use a different label than the parameter name, then this change doesn't make as much sense anymore.

Another concern with this proposal is that, even if you assume most methods with multiple parameters would want to label all the parameters, it's likely that most methods with a single parameter will leave the parameter unlabelled. But this proposed rule would cause even single-argument methods to label the sole argument.

-Kevin Ballard

On Wed, Mar 9, 2016, at 05:03 PM, Jordan Rose via swift-evolution wrote:

This is my concern too. Our guidelines often lead to the first parameter having a label, but usually that name isn't the same as the name of the parameter—one's a preposition, the other's a noun. I'm pretty sure the common case is still unlabeled. Does that justify the complexity of the current rule?

(But because Objective-C methods will now often have labeled arguments, it would at least no longer be a marker differentiating "pure Swift" code from "Cocoa" code.)

Jordan

On Mar 9, 2016, at 14:32, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Looking at my code, the majority of methods should still have the first parameter unlabeled.

I like the consistency of what you’re proposing and the fact that I don’t have to write `func foo(someArgument someArgument: T)` anymore. But I also fear people won’t get it that they can (and in many, probably most, situations should) make the first parameter `_ foo`.

— Radek

On 09 Mar 2016, at 19:58, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

But _ is so easy to type the simplicity of everything is labelled wins for
me. Also remember that inits have 1st argument labels.

  -- Howard.

···

On 11 March 2016 at 09:21, Kevin Ballard via swift-evolution < swift-evolution@swift.org> wrote:

This is a valid concern.

If we assumed that 50% of methods would have a labelled first parameter,
and 50% would leave them unlabelled, and furthermore we assume that all
methods with labelled first parameters would use the parameter name as the
label, then I would support this proposal purely on the grounds that it's
easier to write `func foo(_ bar: T)` than it is to write `func foo(bar bar:
T)`.

However, if we assume that the majority of methods still want an
unlabelled first parameter (which seems like a reasonable assumption to me;
most of the methods I write would certainly have the first parameter
unlabelled), and similarly if we assume that a non-trivial amount of
labelled first parameters use a different label than the parameter name,
then this change doesn't make as much sense anymore.

Another concern with this proposal is that, even if you assume most
methods with multiple parameters would want to label all the parameters,
it's likely that most methods with a single parameter will leave the
parameter unlabelled. But this proposed rule would cause even
single-argument methods to label the sole argument.

-Kevin Ballard

On Wed, Mar 9, 2016, at 05:03 PM, Jordan Rose via swift-evolution wrote:

This is my concern too. Our guidelines often lead to the first parameter
having a label, but usually that name isn't the same as the name of the
parameter—one's a preposition, the other's a noun. I'm pretty sure the
common case is still unlabeled. Does that justify the complexity of the
current rule?

(But because Objective-C methods will now often have labeled arguments, it
would at least no longer be a marker differentiating "pure Swift" code from
"Cocoa" code.)

Jordan

On Mar 9, 2016, at 14:32, Radosław Pietruszewski via swift-evolution < > swift-evolution@swift.org> wrote:

Looking at my code, the majority of methods should still have the first
parameter unlabeled.

I like the consistency of what you’re proposing and the fact that I don’t
have to write `func foo(someArgument someArgument: T)` anymore. But I also
fear people won’t get it that they can (and in many, probably most,
situations should) make the first parameter `_ foo`.

— Radek

On 09 Mar 2016, at 19:58, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote:

Our accepted naming guidelines have embraced first argument labels for
functions and methods. This weakens our justification for making the first
parameter declaration in a `func` declaration behave differently from the
others, implicitly being unlabeled. It seems pretty clear to me we should
make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently,
which is nice. There may still be hope for our keyword argument rules to
one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

*_______________________________________________*
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

If it's easy to get these numbers, how many of the first parameters have the same label as the parameter name?

Jordan

···

On Mar 10, 2016, at 15:34 , Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

on Wed Mar 09 2016, Jordan Rose <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

This is my concern too. Our guidelines often lead to the first
parameter having a label, but usually that name isn't the same as the
name of the parameter—one's a preposition, the other's a noun. I'm
pretty sure the common case is still unlabeled.

It's about 50/50 (slight edge to labeled first parameters) in the
imported Cocoa APIs.

I’m a +1 for this proposal; underscore is easy to add for methods where it does make sense to skip the parameter name, and it would encourage developers to think a little more about how to define it.

···

On 10 Mar 2016, at 22:30, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

But _ is so easy to type the simplicity of everything is labelled wins for me. Also remember that inits have 1st argument labels.

  -- Howard.

On 11 March 2016 at 09:21, Kevin Ballard via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
This is a valid concern.

If we assumed that 50% of methods would have a labelled first parameter, and 50% would leave them unlabelled, and furthermore we assume that all methods with labelled first parameters would use the parameter name as the label, then I would support this proposal purely on the grounds that it's easier to write `func foo(_ bar: T)` than it is to write `func foo(bar bar: T)`.

However, if we assume that the majority of methods still want an unlabelled first parameter (which seems like a reasonable assumption to me; most of the methods I write would certainly have the first parameter unlabelled), and similarly if we assume that a non-trivial amount of labelled first parameters use a different label than the parameter name, then this change doesn't make as much sense anymore.

Another concern with this proposal is that, even if you assume most methods with multiple parameters would want to label all the parameters, it's likely that most methods with a single parameter will leave the parameter unlabelled. But this proposed rule would cause even single-argument methods to label the sole argument.

-Kevin Ballard

On Wed, Mar 9, 2016, at 05:03 PM, Jordan Rose via swift-evolution wrote:

This is my concern too. Our guidelines often lead to the first parameter having a label, but usually that name isn't the same as the name of the parameter—one's a preposition, the other's a noun. I'm pretty sure the common case is still unlabeled. Does that justify the complexity of the current rule?

(But because Objective-C methods will now often have labeled arguments, it would at least no longer be a marker differentiating "pure Swift" code from "Cocoa" code.)

Jordan

On Mar 9, 2016, at 14:32, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Looking at my code, the majority of methods should still have the first parameter unlabeled.

I like the consistency of what you’re proposing and the fact that I don’t have to write `func foo(someArgument someArgument: T)` anymore. But I also fear people won’t get it that they can (and in many, probably most, situations should) make the first parameter `_ foo`.

— Radek

On 09 Mar 2016, at 19:58, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Our accepted naming guidelines have embraced first argument labels for functions and methods. This weakens our justification for making the first parameter declaration in a `func` declaration behave differently from the others, implicitly being unlabeled. It seems pretty clear to me we should make all of the parameter declarations behave uniformly:

func foo(x: Int, y: Int) // Should declare foo(x:y:), instead of foo(_:y:)
func foo(_ x: Int, y: Int) // Explicitly declares foo(_:y:)

This would also make `init` and `func` parameters behave consistently, which is nice. There may still be hope for our keyword argument rules to one day be shorter than the Smalltalk spec…

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

If you're going to measure that, you should also measure it for second, third, ..., Nth parameters too for comparison.

-Joe

···

On Mar 11, 2016, at 11:20 AM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Mar 10, 2016, at 15:34 , Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

on Wed Mar 09 2016, Jordan Rose <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

This is my concern too. Our guidelines often lead to the first
parameter having a label, but usually that name isn't the same as the
name of the parameter—one's a preposition, the other's a noun. I'm
pretty sure the common case is still unlabeled.

It's about 50/50 (slight edge to labeled first parameters) in the
imported Cocoa APIs.

If it's easy to get these numbers, how many of the first parameters have the same label as the parameter name?

Anyone who wants to measure is free to do so: simple regexps and wc generally work for this purpose.

···

On Mar 11, 2016, at 11:27 AM, Joe Groff <jgroff@apple.com> wrote:

On Mar 11, 2016, at 11:20 AM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 10, 2016, at 15:34 , Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

on Wed Mar 09 2016, Jordan Rose <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

This is my concern too. Our guidelines often lead to the first
parameter having a label, but usually that name isn't the same as the
name of the parameter—one's a preposition, the other's a noun. I'm
pretty sure the common case is still unlabeled.

It's about 50/50 (slight edge to labeled first parameters) in the
imported Cocoa APIs.

If it's easy to get these numbers, how many of the first parameters have the same label as the parameter name?

If you're going to measure that, you should also measure it for second, third, ..., Nth parameters too for comparison.

…in retrospect, probably more of the Cocoa names would match up if they had this shorthand before:

  func beginSheetModal(for window: NSWindow, modalDelegate delegate: AnyObject?, didEnd didEndSelector: Selector, contextInfo contextInfo: UnsafeMutablePointer<Void>)

- for/window is a true difference
- modalDelegate/delegate is just convenience inside the method; it could have easily been modalDelegate/modalDelegate
- didEnd/didEndSelector actually does match up in the original; the importer has (correctly) changed it to not match
- contextInfo/contextInfo is a match

So I'm not convinced results for the later parameters are meaningful. Haven't looked at first parameters yet.

Jordan

···

On Mar 11, 2016, at 13:30 , Dave Abrahams <dabrahams@apple.com> wrote:

On Mar 11, 2016, at 11:27 AM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

On Mar 11, 2016, at 11:20 AM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 10, 2016, at 15:34 , Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

on Wed Mar 09 2016, Jordan Rose <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

This is my concern too. Our guidelines often lead to the first
parameter having a label, but usually that name isn't the same as the
name of the parameter—one's a preposition, the other's a noun. I'm
pretty sure the common case is still unlabeled.

It's about 50/50 (slight edge to labeled first parameters) in the
imported Cocoa APIs.

If it's easy to get these numbers, how many of the first parameters have the same label as the parameter name?

If you're going to measure that, you should also measure it for second, third, ..., Nth parameters too for comparison.

Anyone who wants to measure is free to do so: simple regexps and wc generally work for this purpose.

https://github.com/apple/swift-3-api-guidelines-review/tree/swift-3/Platforms

Not sure if anyone actually got around to this so doing a basic set of
regex (includes class functions and overrides)...

func foo(bar baz:Baz... ---> 10544
func foo(baz:Baz... ---> 526
func foo(_:Baz... ---> 92
func foo() ---> 7392

···

On Fri, Mar 11, 2016 at 1:30 PM Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

Anyone who wants to measure is free to do so: simple regexps and wc
generally work for this purpose.

https://github.com/apple/swift-3-api-guidelines-review/tree/swift-3/Platforms

This is my concern too. Our guidelines often lead to the first
parameter having a label, but usually that name isn't the same as the
name of the parameter—one's a preposition, the other's a noun. I'm
pretty sure the common case is still unlabeled.

It's about 50/50 (slight edge to labeled first parameters) in the
imported Cocoa APIs.

If it's easy to get these numbers, how many of the first parameters have the same label as the parameter name?

If you're going to measure that, you should also measure it for second, third, ..., Nth parameters too for comparison.

Anyone who wants to measure is free to do so: simple regexps and wc generally work for this purpose.

https://github.com/apple/swift-3-api-guidelines-review/tree/swift-3/Platforms

…in retrospect, probably more of the Cocoa names would match up if they had this shorthand before:

  func beginSheetModal(for window: NSWindow, modalDelegate delegate: AnyObject?, didEnd didEndSelector: Selector, contextInfo contextInfo: UnsafeMutablePointer<Void>)

- for/window is a true difference
- modalDelegate/delegate is just convenience inside the method; it could have easily been modalDelegate/modalDelegate
- didEnd/didEndSelector actually does match up in the original; the importer has (correctly) changed it to not match
- contextInfo/contextInfo is a match

Sorry, I don’t know what you are trying to assert here. Which shorthand? We haven’t introduced any, and nobody’s proposing to add one.

···

On Mar 11, 2016, at 2:57 PM, Jordan Rose <jordan_rose@apple.com> wrote:

On Mar 11, 2016, at 13:30 , Dave Abrahams <dabrahams@apple.com <mailto:dabrahams@apple.com>> wrote:

On Mar 11, 2016, at 11:27 AM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

On Mar 11, 2016, at 11:20 AM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 10, 2016, at 15:34 , Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
on Wed Mar 09 2016, Jordan Rose <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

So I'm not convinced results for the later parameters are meaningful. Haven't looked at first parameters yet.

Jordan

Interesting — but I don’t think framework APIs are necessarily representative of Swift usage at large. I suspect most Swift being done today is in application contexts. And, I don’t have the exact numbers, but when I played around with extracting method signatures from my projects, it seemed like the *majority* of methods should continue to be `func foo(bar: T)`, not `func foo(bar bar: T)`.

— Radek

···

On 13 Mar 2016, at 23:29, Shawn Erickson via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, Mar 11, 2016 at 1:30 PM Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Anyone who wants to measure is free to do so: simple regexps and wc generally work for this purpose.

https://github.com/apple/swift-3-api-guidelines-review/tree/swift-3/Platforms

Not sure if anyone actually got around to this so doing a basic set of regex (includes class functions and overrides)...

func foo(bar baz:Baz... ---> 10544
func foo(baz:Baz... ---> 526
func foo(_:Baz... ---> 92
func foo() ---> 7392
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution