<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=""><blockquote type="cite" class=""><div class="">On Jan 27, 2016, at 10:09, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""></div><div class="">I’m sorry, I’ve lost context on what the proposal here is. &nbsp;Can you please restate it? &nbsp;To me, it seems most natural that $0 always refer to the first parameter of a closure.</div><div class=""><br class=""></div><div class="">-Chris</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Paul Cantrell’s original post documented behavior which causes $0 to sometimes refer to a tuple of all the arguments instead of the just first argument. John McCall&nbsp;said it was bug, but then Jordan Rose replied and said, ”I wouldn’t go as far as to say it’s a bug. It’s known and occasionally useful for forwarding arguments". My understanding is that everyone agrees on two things: the bug should eventually be fixed, and the bug’s functionality is actually kinda cool (when it’s not biting you) and there should still be a way to invoke it. The debate was over whether to do it now and make $*, $_, $$, $…, or $# (I think that’s all of them) be the “all args” tuple, or whether we should wait fix it until Swift gets “a more complete revision of the varargs system” (which was assumed to be at least Swift 4).</div><div class=""><br class=""></div><div class="">At least that’s how I understand it. Here’s Paul’s original post:</div><div class=""><br class=""></div><div class=""><div class="">- Dave Sweeris</div><div class=""><br class=""></div><div class=""><div class=""></div></div><blockquote type="cite" class=""><div class=""><div class="">On Jan 19, 2016, at 19:20, Paul Cantrell 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=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Surprisingly, this code does not compile:<div class=""><br class=""></div><div class=""><div class=""><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;"><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">func</span>&nbsp;foo(val:&nbsp;<span class="" style="color: rgb(88, 126, 168);">Int</span>) { }</div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; min-height: 12px;"><br class=""></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(50, 62, 125);">func</span>&nbsp;bar(closure: (<span class="" style="color: rgb(88, 126, 168);">Int</span>,<span class="" style="color: rgb(88, 126, 168);">Int</span>) -&gt;&nbsp;<span class="" style="color: rgb(88, 126, 168);">Void</span>) {</div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;">&nbsp; &nbsp; &nbsp; &nbsp; closure(<span class="" style="color: rgb(50, 62, 125);">0</span>,&nbsp;<span class="" style="color: rgb(50, 62, 125);">1</span>)</div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;">&nbsp; &nbsp; }</div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; min-height: 12px;"><br class=""></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(88, 126, 168);">bar</span>&nbsp;{&nbsp;<span class="" style="color: rgb(88, 126, 168);">foo</span>($0) } &nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(102, 139, 73);">// compiler error</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(88, 126, 168);">bar</span>&nbsp;{&nbsp;<span class="" style="color: rgb(88, 126, 168);">foo</span>($1) } &nbsp; &nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(102, 139, 73);">// just dandy</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal;">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(88, 126, 168);">bar</span>&nbsp;{&nbsp;<span class="" style="color: rgb(88, 126, 168);">foo</span>($0 + $1) }&nbsp;&nbsp;<span class="" style="color: rgb(102, 139, 73);">// also works</span></div><div class=""><span class="" style="color: rgb(102, 139, 73);"><br class=""></span></div></div></div></div><div class="">The compiler error is:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; Cannot convert value of type (Int, Int) to expected argument type Int</div></div><div class=""><br class=""></div><div class="">It appears that the meaning of&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">$0</span>&nbsp;is overloaded: it can refer either to the tuple of all arguments, or to just the first argument. The presence of another placeholder variable (<span class="" style="font-family: Menlo; font-size: 11px;">$1</span>&nbsp;in the third example) seems to trigger the latter behavior.</div><div class=""><br class=""></div><div class="">This is certainly confusing. I’m posting to the list after receiving two Siesta user questions in the same day that both boil down to this issue.</div><div class=""><br class=""></div><div class="">Even if you do understand the behavior, it’s a real nuisance: it prevents concise implementation of a multi-arg closure which wants to ignore all but its first argument. Instead, such a closure has to drop back to the more verbose syntax:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(88, 126, 168);">&nbsp; &nbsp; bar</span>&nbsp;{ a, _&nbsp;<span class="" style="color: rgb(50, 62, 125);">in</span>&nbsp;<span class="" style="color: rgb(88, 126, 168);">foo</span>(a) } &nbsp;&nbsp;<span class="" style="color: rgb(102, 139, 73);">// sigh</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;"><br class=""></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;"><span class="" style="font-family: 'Helvetica Neue'; font-size: 13px;">…or use this legibility-proof workaround:</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;"><span class="" style="font-family: 'Helvetica Neue'; font-size: 13px;"><br class=""></span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(88, 126, 168);">&nbsp; &nbsp; bar</span>&nbsp;{&nbsp;<span class="" style="color: rgb(88, 126, 168);">foo</span>($0.<span class="" style="color: rgb(50, 62, 125);">0</span>) } &nbsp;&nbsp;<span class="" style="color: rgb(102, 139, 73);">// yuck! wat?!</span></div></div><div class=""><span class="" style="color: rgb(102, 139, 73);"><br class=""></span></div><div class="">(Note that this problem exists only for the&nbsp;<i class="">first</i>&nbsp;argument; a closure that wants to ignore all but the&nbsp;<i class="">second</i>&nbsp;has no such problem.)</div><div class=""><br class=""></div><div class="">This behavior contradicts the Swift documentation, which clearly says that&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">$0</span>&nbsp;refers to the first argument:</div><div class=""><br class=""></div><blockquote type="cite" class="">Swift automatically provides shorthand argument names to inline closures, which can be used to refer&nbsp;to the values of the closure’s arguments by the names&nbsp;$0,&nbsp;$1,&nbsp;$2, and so on.<br class=""></blockquote><br class=""><div class="">And:</div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class="">A closure may omit names for its parameters. Its parameters are then implicitly named&nbsp;$&nbsp;followed by their position:&nbsp;$0,&nbsp;$1,&nbsp;$2, and so on.</blockquote></div></div><div class=""><br class=""></div><div class="">I can’t find anything in the docs that mentions this “all args tuple” behavior, so perhaps it’s a bug? Let me know if it is, and I’ll just file a bug report for it.</div><div class=""><br class=""></div><div class="">However the “whole tuple” behavior does seem to be intentional, and preserving that while fixing the problem above appears to require a language change. Thus…</div><div class=""><br class=""></div><div class=""><b class="">Proposal</b></div><div class=""><br class=""></div><div class="">The implicit closure variable&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">$0</span>&nbsp;should always refer to the closure’s first argument, and a different implicit name — perhaps&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">$*</span>&nbsp;or&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">$_</span>&nbsp;or&nbsp;<span class="" style="font-family: Menlo; font-size: 11px;">$...</span>&nbsp;— should refer to the all-args tuple.</div><div class=""><br class=""></div><div class="">Thoughts?</div><div class=""><br class=""></div><div class="">Cheers,</div><div class=""><br class=""></div><div class="">Paul</div><div class=""><br class=""></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></div></blockquote><div class=""><br class=""></div></div></body></html>