SE-0255: Implicit Returns from Single-Expression Functions

Most of the discussion about excluding functions from this proposal talks about instance methods, but I think nested functions should also be considered. If you want to extract some code into a local helper in a complex function you could write a closure:

func complexFunction<T: FloatingPoint>(…) {
  let score: ([T], [T]) -> T = { zip($0, $1).map(*).reduce(0, +) }
  …  
  let s = score([1, 2, 3], [4, 5, 6]))
  …
}

but you might decide you want to label the arguments and write a nested function instead

func complexFunction<T: FloatingPoint>(…) {
  func score(values: [T], weights: [T]) -> T { zip(values, weights).map(*).reduce(0, +) }
  …
  let s = score(values: [1, 2, 3], weights: [4, 5, 6]))
  …
}
// Error: Missing return in a function expected to return 'T'

Perhaps in future you will be able to label closure arguments (an as-yet-unrealised followup to SE-011) which would either make this less persuasive (“just use a closure instead”) or more persuasive (“there are now even fewer differences between closures and functions but you still can't elide the return from functions”) depending on your perspective. Similar is true of other oft-rumoured features, like allowing closure properties to satisfy method requirements on protocols.

6 Likes