[swift-evolution] Lambda function syntax

Thorsten Seitz trsfoo at googlemail.com
Sun Dec 27 13:01:24 CST 2015


In this mail I’m answering several statements made in this thread by different people, not only Brent’s mail from which I just picked the following snippet:

> let names = people.map => person { person.name }

For me that is more difficult to read than

	let names = people.map { person in person.name }

Especially when chaining is used, i.e.

	let names = people.filter => person { person.isFriend }.map => person { person.name }

(or would I have to add parentheses somewhere with this proposed syntax?)

vs.

	let names = people.filter { person in person.isFriend }.map { person in person.name }


Those „=>“ pretty much visually separate the statement in the wrong positions, i.e. the parts grouped together visually are

1. people.filter
2. person { person.isFriend }.map
3. person { person.name }

which is simply wrong for the middle part (or parts in case of more chaining).

Whereas having the arguments in the closure separate the parts visually much better, keeping the closures together and interspersed with the function names.


With regards to trailing closures: Having them is an important part of DSLs in Ruby, Smalltalk and Scala.

See for example the links cited in https://news.ycombinator.com/item?id=7921011 or the Akka library (http://akka.io) or rake (Ruby’s „make" replacement).

Of course Alexander is right that the concept of a trailing closure works only for one closure and not for several. That is indeed a thing where Smalltalk’s syntax without any parentheses around function arguments had a really nice advantage which is not possible in Swift (although the parameter keywords are really great in alleviating this).
But there are so many cases (as the links above demonstrate) where a single trailing closure is sufficient that this feature is tremendously useful.


With regards to Haskell: the above example would (typically) look like:

names = map (\person -> name person) . filter (\person -> isFriend person) $ people

which also uses only one pair of parentheses just around the lambda expressions (because Haskell has neither parentheses around parameters nor around closures).

Visually it actually looks just the same as Swift’s closures (replacing parentheses with braces and „->“ with „in“ and dropping the backslash which stands in for the greek letter lambda), i.e. visually the parameters of the closure are within the parentheses, just like in Swift.
Of course the syntactical meaning of the parentheses is different from that of the braces but the visual effect is quite important in my eyes. That helps a lot in readability.


With regards to „in“: I personally like it but could also live with something like „=>“ or the bar „|“ as used in Ruby (two bars around the params) or Smalltalk (just one bar after the params which I would prefer), e.g.

let names = people.map { person | person.name }

although the „in“ definitely looks better with syntax highlighting and when using the wrong font like now (where the bar just looks like the upper case letter „i“).

I think I said it already: the „in“ reminds me of the let-in-expression of Haskell, e.g. „let foo = 3 in …“


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


More information about the swift-evolution mailing list