<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><blockquote type="cite" class=""><div class="">On Jan 19, 2016, at 7:20 PM, Paul Cantrell via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> 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="">Surprisingly, this code does not compile:<div class=""><br class=""></div><div class=""><div class=""><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> foo(val: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Int</span>) { }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> bar(closure: (<span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Int</span>,<span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Int</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Void</span>) {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""> closure(<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">0</span>, <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">1</span>)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""> }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">bar</span> { <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">foo</span>($0) } <span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class="">// compiler error</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">bar</span> { <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">foo</span>($1) } <span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class="">// just dandy</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">bar</span> { <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">foo</span>($0 + $1) } <span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class="">// also works</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class=""><br class=""></span></div></div></div></div><div class="">The compiler error is:</div><div class=""><br class=""></div><div class=""> 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 <span style="font-family: Menlo; font-size: 11px;" class="">$0</span> 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 style="font-family: Menlo; font-size: 11px;" class="">$1</span> in the third example) seems to trigger the latter behavior.</div></div></div></blockquote><div><br class=""></div>It’s dumber than that. The type-checker assumes that the closure has a tuple of arguments ($0, $1, …, $N), where $N is the largest N seen in the closure. Thus, a two-argument closure falls down if you ignore the second argument. It’s dumb, and we’ve known about it for a long time; and yet it’s been remarkably annoying to fix, and so we haven’t yet.</div><div><br class=""></div><div>Anyway, it’s a bug and doesn’t need to go through evolution.</div><div><br class=""></div><div>John.</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><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 style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class=""> bar</span> { a, _ <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">in</span> <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">foo</span>(a) } <span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class="">// sigh</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><span style="font-family: 'Helvetica Neue'; font-size: 13px;" class="">…or use this legibility-proof workaround:</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><span style="font-family: 'Helvetica Neue'; font-size: 13px;" class=""><br class=""></span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class=""> bar</span> { <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">foo</span>($0.<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">0</span>) } <span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class="">// yuck! wat?!</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class=""><br class=""></span></div><div class="">(Note that this problem exists only for the <i class="">first</i> argument; a closure that wants to ignore all but the <i class="">second</i> has no such problem.)</div><div class=""><br class=""></div><div class="">This behavior contradicts the Swift documentation, which clearly says that <span style="font-family: Menlo; font-size: 11px;" class="">$0</span> 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 to the values of the closure’s arguments by the names $0, $1, $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 $ followed by their position: $0, $1, $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 <span style="font-family: Menlo; font-size: 11px;" class="">$0</span> should always refer to the closure’s first argument, and a different implicit name — perhaps <span style="font-family: Menlo; font-size: 11px;" class="">$*</span> or <span style="font-family: Menlo; font-size: 11px;" class="">$_</span> or <span style="font-family: Menlo; font-size: 11px;" class="">$...</span> — 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></blockquote></div><br class=""></body></html>