Everyone loves this syntax:

  let pos = [1, -2, 3].map(abs)

This syntax not so much:

  let neg = [1, -2, 3].map({ -abs($0) })

For single-statement closures, ordered parameters could be referenced in an 
autoclosure-like way using a placeholder for the parameter:

  let neg = [1, -2, 3].map(-abs(_))

The behavior would be the same as the current $0, $1, ... shorthand argument 
names to inline closures except that parameter re-ordering wouldn't be allowed 
(the first instance of _ would be $0, the second would be $1, etc). So the 
following three lines would all be compiled the same:

  let reversed = words.sort( { $0 > $1 } )
  let reversed = words.sort(_ > _)
  let reversed = words.sort(>)

As with autoclosures, noescape rules would be enforced since there wouldn't be 
any way to specify that self is weak or unowned. So while the following 
requires use of self to make capture semantics explicit:

  words.lazy.filter({ $0.hashValue == self.hashValue })

These would both raise errors:

  words.lazy.filter(_.hashValue == hashValue)
  words.lazy.filter(_.hashValue == self.hashValue)

Nested closures would also behave the same as with dollar-shorthand:

  let words = ["abc", "def", "hij"]
  let ascii = words.flatMap({ $0.unicodeScalars.filter({ $0.isASCII }) })
  let ascii = words.flatMap(_.unicodeScalars.filter(_.isASCII))

Another example:

  let words: [String?] = ["Hey", "you", nil, "guys"]
  let exclaim = words.flatMap({ $0 }).map({ $0.uppercaseString }).reduce("", 
combine: { $0+"! "+$1 })
  let exclaim = words.flatMap(_).map(_.uppercaseString).reduce("", combine: 
_+"! "+_)


Why underscore and not another character like a lone "$" or "."? The meaning of 
the underscore character as an anonymous ordered placeholder would be 
consistent with other usages throughout the Swift language. Examples:

  let (_, two, _) = (1, 2.0, "Three") // anonymous tuple property
  words.reduce("", combine: { (x, _) in x }) // anonymous closure parameter
  let advancer = Int.advancedBy(_:limit:) // anonymous function argument
  switch "X" as String? {
  case .Some(_): print("something") // anonymous enum value
  case .None: print("nothing")
  }

And since underscore currently isn't allowed on the right-hand side of an 
expression, this syntax enhancement shouldn't break any existing code. Lastly, 
this same syntax for anonymous arguments is used in Scala, so it would already 
be familiar to a large developer base.

Any yeas or nays?

        -Marc

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to