SE-0066: The one-argument function outlier

Swift requires parentheses when you declare a function:

f(x: T) -> U

Swift requires parentheses when you call a function

let _ = f(value)

Swift only requires parentheses when you declare a function type if the function takes 2 or more arguments:

let g1: (T) -> U // legal
let g2: T -> U // legal
let g3: (T, U) -> V // legal
let g4: T, U -> V // illegal

SE-0066 proposes to standardize function type argument syntax and discard that one legal outlier case (g2).  It introduces no changes to the syntactic sugar used for closure short-hand. All it does is clean up this one outlier case.

This proposal has led to heated discussion on the Swift Evolution list with Alan Skipp representing the surprisingly large push-back. He writes, “I’d place the ability to omit parenthesises for single args in the same category as being able to omit `self` when accessing properties. They are small conveniences that make a large difference to an entire codebase.”

John McCall writes, “To me, the unparenthesized style suggests that the input and output are peers, which feels more natural for the sort of value-to-value transform/predicate where this most commonly occurs.”

Radosław Pietruszewski writes, “To me, `func blah(f: Int -> Float) -> String` is easier to read that `func blah(f: (Int) -> Float) -> String`.” He also has concerns regarding Swift’s future should Swift adopt higher order functions.

Some list participants feel that (T, U) -> (V, W) reads more as tuple-to-tuple than 2-arguments-to-tuple. The actual tuple-to-tuple declaration is ((T, U)) -> (V, W) and would not be affected by this proposal.

Even the Void typealias has come under fire, with some members requesting that it be entirely banned.

Personally, I like SE-0066 and support its adoption. I also much prefer `func blah(f: (Int) -> Float) -> String` to `func blah(f: Int -> Float) -> String`. To me the consistency outweighs any minor savings in the odd parenthesis here and there, and clarifies the domain-to-range projection over using input and output peers.

Chris Lattner writes, “[R]egardless of why we always require parentheses on Decls and ApplyExprs, we really do (and that isn’t going to change).  Being consistent between func decls and function types is quite important IMO.”

If you’d like to jump into the discussion, SE-0066 should be up for review soon and the discussion on the initial pitch is active…and lively.

Comments are closed.