I use trailing closures all the time because I find the brackets too noisy, like ; at the end of a line is too noisy. The sort of code I use is:
let foo = myArray .filter { $0 & 1 == 1 } .map { $0 + 1 } .reduce(0) { $0 + $1 } On Friday, 25 March 2016, Haravikk via swift-evolution < swift-evolution@swift.org> wrote: > When I started using Swift I was initially very enthusiastic about > trailing closures, but I’ve actually kind of gone off them somewhat and I’d > like to discuss why. > > Firstly, here are two ways to write a common example using the .map() > method: > > let foo = myArray.map { $0 + 1 } > let foo = myArray.map({ $0 + 1 }) > > It’s tough to say that the first form is any neater than the second, other > than the second having more brackets. However, the first form is somewhat > ambiguous, as .map in this case looks like a property rather than a method, > it also visually looks like a statement, followed by a closure rather than > the two things logically being related. Of course it’s quick to learn that > these are related, but for consistency I’m starting to now prefer the use > of parenthesis in almost all cases. > > The other advantage of trailing closures is the omission of the label, but > trailing closures aren’t strictly necessary for this, as we can already > omit external labels for parameters if we want to, and the example above > shows that a trailing closure isn’t necessary for this. The only real > difference is that the trailing closure form makes a label optional, > because you can either provide the closure with label in parenthesis (if > the label is required) or omit it by trailing, like so: > > something.someMethod(foo: 1, predicate: { $0 < $1}) > something.someMethod(foo: 1) { $0 < $1} > > However this kind of arbitrarily makes the following impossible: > > something.someMethod(foo: 1, { $0 < $1 }) > > With this in mind it seems to me that we might be better served by the > ability to make external labels optional, as this would allow us to be just > as succinct, while being completely clear about what is being passed into > this method. > > > The only real remaining advantage that I see to trailing closures is the > ability to define pseudo language constructs, for example: > > func repeatUntilEmpty<C:CollectionType>(collection:C, @noescape _ body:() > throws -> Void) rethrows { while !collection.isEmpty { body() } } > repeatUntilEmpty(myArray) { > /* Do something over and over until myArray is empty */ > } > > Which I think is a pretty uncommon type of structure, but could be useful > in some specialised situations. To support this though we could easily use > a new @trailing attribute instead to indicate that the closure can be used > in this way. My example isn’t very good as I can’t think of a case that > really, really needs this, but I think they’re probably out there. > > > To summarise, having come down off my initial enthusiasm for trailing > closures I’m not sure that they really add that much syntactically, > especially in the most common cases, while actually being a little > ambiguous looking and adding inconsistency to the language. I think they > should remain for the less common cases that can really benefit from them, > but as a feature that is opted into, so that we can go for consistency by > default. > > I’m interested to hear other people’s thoughts. > -- -- Howard.
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution