[swift-evolution] [Draft] Make the first parameter in a function declaration follow the same rules as the others

Erica Sadun erica at ericasadun.com
Wed Mar 9 19:02:29 CST 2016


> On Mar 9, 2016, at 11:58 AM, Joe Groff via swift-evolution <swift-evolution at 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 <http://twitter.com/jckarter/status/707691862836924416>
gist:  		https://gist.github.com/erica/e83893998ca7b5f46afe <https://gist.github.com/erica/e83893998ca7b5f46afe>
Pull request: 	https://github.com/apple/swift-evolution/pull/200 <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.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160309/b5f05495/attachment.html>


More information about the swift-evolution mailing list