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


(Joe Groff) #1

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


(David Owens II) #2

+1000000000000000 =)

-David

···

On Mar 9, 2016, at 10: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


(Erica Sadun) #3

+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


(Chéyo Jiménez) #4

+1 Yes

the current solution makes me wish we still have the # from swift 1 :wink:

  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> 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


(Brent Royal-Gordon) #5

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…

+1. (This was actually in my mental list of things to propose.)

I believe this leaves only subscripts with a rule that doesn't label all parameters. Subscripts (or at least unary subscripts) *should* usually have unlabeled parameters, but having a single rule might be worth requiring `_` in those.

I also think there's a good case for bringing back something like the old `#foo`, but that's a separable issue.

···

--
Brent Royal-Gordon
Architechies


(Sean Heber) #6

+0.8 - change is hard. :stuck_out_tongue:

l8r
Sean

···

On Mar 9, 2016, at 12:58 PM, 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


(Austin Zheng) #7

+1. Would definitely like to see this change make it in.

···

On Wed, Mar 9, 2016 at 10: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


(Trent Nadeau) #8

+1

Please, please, please! :slight_smile:

···

On Wed, Mar 9, 2016 at 1:58 PM, 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

--
Trent Nadeau


(Erica Sadun) #9

tweet: http://twitter.com/jckarter/status/707691862836924416
gist: https://gist.github.com/erica/e83893998ca7b5f46afe
Pull request: https://github.com/apple/swift-evolution/pull/200

Establish consistent label behavior across all parameters including first labels

Proposal: TBD
Author(s): Joe Groff <http://github.com/jckarter>, Jake Carter <https://github.com/JakeCarter>, Erica Sadun <http://github.com/erica>
Status: TBD
Review manager: TBD
<https://gist.github.com/erica/e83893998ca7b5f46afe#introduction>Introduction

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> thread.

<https://gist.github.com/erica/e83893998ca7b5f46afe#motivation>Motivation

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/> 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> 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.

<https://gist.github.com/erica/e83893998ca7b5f46afe#detail-design>Detail 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:)

<https://gist.github.com/erica/e83893998ca7b5f46afe#impact-on-existing-code>Impact 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.

<https://gist.github.com/erica/e83893998ca7b5f46afe#alternatives-considered>Alternatives Considered

There are no alternatives considered at this time.

···

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


(Ben Rimmington) #10

+1

I'd like the same rules for subscripts:

e.g. public subscript (_ index: Int) -> Element

And also for closures, so that the Clang Importer can use the same block parameter names as Objective-C:

e.g. public func enumerateByteRanges(_ block: (_ bytes: UnsafePointer<Void>, _ byteRange: NSRange, _ stop: UnsafeMutablePointer<ObjCBool>) -> Void)

The latter wouldn't affect public API, but could be used in Xcode's auto-completion of the trailing closure.

-- Ben

···

On 9 Mar 2016, at 18: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


(Tino) #11

+0.9
Although I favor a different approach discussed in an old thread, the major goal in this discussion was unification.

I'm not that sure that a labeled first parameter is the best choice for the majority of methods, but I'm confident to find ways to avoid most underscores :wink:

Tino


(Rudolf Adamkovič) #12

+1

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

R+

···

On 9 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


(Radek Pietruszewski) #13

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


(Howard Lovatt) #14

Definite +1 from me.

···

On Thursday, 10 March 2016, 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

--
-- Howard.


(Adrian Kashivskyy) #15

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


(Brent Royal-Gordon) #16

I also think there's a good case for bringing back something like the old `#foo`, but that's a separable issue.

Wait, what was I thinking? Scratch that.

···

--
Brent Royal-Gordon
Architechies


(Tanner) #17

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.

···

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 :wink:

  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


(Jordan Rose) #18

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 <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


(Joe Groff) #19

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?

I think it's also common under our guidelines for the second argument label to not make sense as a parameter name, since it's often also a preposition, e.g. `move(from origin: T, to destination: U)`.

-Joe

···

On Mar 9, 2016, at 5:03 PM, Jordan Rose <jordan_rose@apple.com> wrote:

(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


(Jonathan Tang) #20

+1. As a newbie to Swift, the special first-argument rules caused no end
of confusion. As a more experienced Swift dev, I find that I use a first
argument label fairly frequently, and it's one less rule to remember.

···

On Wed, Mar 9, 2016 at 5:02 PM, 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> 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: https://gist.github.com/erica/e83893998ca7b5f46afe
Pull request: https://github.com/apple/swift-evolution/pull/200

Establish consistent label behavior across all parameters including first
labels

   - Proposal: TBD
   - Author(s): Joe Groff <http://github.com/jckarter>, Jake Carter
   <https://github.com/JakeCarter>, Erica Sadun <http://github.com/erica>
   - Status: TBD
   - Review manager: TBD

<https://gist.github.com/erica/e83893998ca7b5f46afe#introduction>
Introduction

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> thread.*
<https://gist.github.com/erica/e83893998ca7b5f46afe#motivation>Motivation

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/> 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> 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.
<https://gist.github.com/erica/e83893998ca7b5f46afe#detail-design>Detail
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:)

<https://gist.github.com/erica/e83893998ca7b5f46afe#impact-on-existing-code>Impact
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.

<https://gist.github.com/erica/e83893998ca7b5f46afe#alternatives-considered>Alternatives
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