Ever since SE-0111, argument labels have not been part of function types. While this makes sense, it leads to a dearth of labels that can be difficult to work with.
This prompts a question: where do argument labels live? They aren’t in the type, and they obviously aren’t in the body. That leaves one place: the name.
This is already acknowledged in documentation, such as the following excerpts from the Language Guide:
The
print(_:separator:terminator:)
function doesn’t have a label for its first argument, and its other arguments are optional because they have a default value.
Here’s a function called
chooseStepFunction(backward:)
, whose return type is(Int) -> Int
. ThechooseStepFunction(backward:)
function returns thestepForward(_:)
function or thestepBackward(_:)
function based on a Boolean parameter calledbackward
:
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
return backward ? stepBackward : stepForward
}
I propose making this an actual part of the language, such that argument labels can be specified in an identifier:
// identifier: “instance”; type: Int
let instance = 42
// identifier: “firstMethod(_:)”; type: (Int) -> Bool
let firstMethod = instance.isMultiple
// identifier: “firstResult”; type: Bool
let firstResult = firstMethod(8)
// identifier: “secondMethod(_:)”; type: (Int) -> Bool
let secondMethod(_:) = firstMethod
// identifier: “secondResult”; type: Bool
let secondResult = secondMethod(6)
// identifier: “possibleProduct(from:)”; type: (Int) -> Bool
let possibleProduct(from:) = secondMethod
// identifier: “thirdResult”; type: Bool
let thirdResult = possibleProduct(from: 7)
This syntax is currently prohibited by the compiler, so it wouldn’t cause any breaking changes. The behavior of existing identifiers would be completely unchanged, since they would implicitly continue to have no argument labels.
The nomenclature has already been tacitly accepted by the Swift community for years, so I think it would be an excellent addition to Swift.