<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I have to admit I’m quite fond of the trailing closure syntax. This is partly because of my earlier experiences with Ruby. But partly I just really found it more readable to see a separation between a regular function call, with just normal parameters passed in, and higher order functions, like the `map` example you’ve made. Having two sets of parentheses/braces like foo({ … }) really makes them blend in and I don’t notice the curly braces as much. Having a stylistic separation between:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>foo(argument)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>foo { code }</div><div class=""><br class=""></div><div class="">helps me catch the difference between the two.</div><div class=""><br class=""></div><div class="">But it is a stylistic choice. Like I mentioned in a different reply, if we’re going to have trailing closures at all, I don’t see a point in enforcing this other than with a linter.</div><div class=""><br class=""></div><div class="">* * *</div><div class=""><br class=""></div><div class="">The <i class="">only</i>&nbsp;way I see this working is if the trailing closure syntax has *other* semantics as well. For example, there’s been a discussion about allowing specially marked closures to return/break/continue in the scope of the caller function, not the closure’s scope (like Ruby’s blocks do). Now, that would make a bit more sense. You’d have a special attribute (can’t think of a name, but let’s stick with your @trailing), that would imply:</div><div class=""><br class=""></div><div class="">- required trailing closure syntax</div><div class="">- @noescape, I think</div><div class="">- and return/break/continue affects outside functions</div><div class=""><br class=""></div><div class="">And you could use that to make your own pseudo-language-constructs. This would enforce trailing closure syntax, and nothing else could use trailing closure syntax.</div><div class=""><br class=""></div><div class="">Now, I wouldn’t be super happy about not being able to write `map { foo }` myself 😁 — but _that_ proposal would make sense to me. It wouldn’t just be enforcement of a stylistic choice, but the syntax would actually convey some important semantics.</div><div class=""><br class=""></div><div class="">What do you think?</div><br class=""><div class="">
<div class="">— Radek</div>
</div>
<br class=""><div><blockquote type="cite" class=""><div class="">On 24 Mar 2016, at 14:57, Haravikk via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">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.<div class=""><br class=""></div><div class="">Firstly, here are two ways to write a common example using the .map() method:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let foo = myArray.map { $0 + 1 }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let foo = myArray.map({ $0 + 1 })</font></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>something.someMethod(foo: 1, predicate: { $0 &lt; $1})</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>something.someMethod(foo: 1) { $0 &lt; $1}</font></div><div class=""><br class=""></div><div class="">However this kind of arbitrarily makes the following impossible:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>something.someMethod(foo: 1, { $0 &lt; $1 })</font></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">The only real remaining advantage that I see to trailing closures is the ability to define pseudo language constructs, for example:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func repeatUntilEmpty&lt;C:CollectionType&gt;(collection:C, @noescape _ body:() throws -&gt; Void) rethrows { while !collection.isEmpty { body() } }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></font><span style="font-family: Monaco;" class="">repeatUntilEmpty(myArray)</span><font face="Monaco" class="">&nbsp;{</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>/* Do something over and over until myArray is empty */</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">I’m interested to hear other people’s thoughts.</div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>