<div dir="ltr">Some good arguments regarding warnings and multiple closures. But I can&#39;t help that feel when designing an API, if you have to add a convenience method that takes just one closure simply to call the real method, this is exactly the sort of boilerplate code that default arguments are supposed to replace.<br></div><br><div class="gmail_quote"><div dir="ltr">On Thu, 5 Jan 2017 at 05:48 Douglas Gregor &lt;<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Jan 4, 2017, at 9:44 PM, Saagar Jha &lt;<a href="mailto:saagar@saagarjha.com" class="gmail_msg" target="_blank">saagar@saagarjha.com</a>&gt; wrote:</div><br class="m_-994319049499522620Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg">So, then this should have a warning? I’m still not getting one.<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">func foo(a: () -&gt; (), b: (() -&gt; ())? = nil, c: Int) {</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>a()</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>b?()</div><div class="gmail_msg">}</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">foo(a: {</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>print(“Bar”)</div><div class="gmail_msg">}, c: 0)</div><div class="gmail_msg"><br class="gmail_msg"></div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">If you give “c” a default value (e.g., “= 0”), it will give a warning.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I’m happy for the warning to get more eager, so long as it also gets a Fix-It at the same time.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>- Doug</div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><span style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">Saagar Jha</span><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">
</div>
<br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Jan 4, 2017, at 9:34 PM, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com" class="gmail_msg" target="_blank">dgregor@apple.com</a>&gt; wrote:</div><br class="m_-994319049499522620Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Jan 4, 2017, at 9:32 PM, Saagar Jha &lt;<a href="mailto:saagar@saagarjha.com" class="gmail_msg" target="_blank">saagar@saagarjha.com</a>&gt; wrote:</div><br class="m_-994319049499522620Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg">
<br class="m_-994319049499522620Apple-interchange-newline gmail_msg"><span style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">Saagar Jha</span><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">
</div>
<br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Jan 4, 2017, at 8:35 PM, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com" class="gmail_msg" target="_blank">dgregor@apple.com</a>&gt; wrote:</div><br class="m_-994319049499522620Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="font-family:SFUIText-Regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br class="m_-994319049499522620Apple-interchange-newline gmail_msg">On Jan 4, 2017, at 7:48 PM, Saagar Jha via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg"><br class="gmail_msg"></div><blockquote type="cite" style="font-family:SFUIText-Regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><div class="gmail_msg">Check out <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160606/020470.html" class="gmail_msg" target="_blank">this thread</a>–it’s very similar to what you proposed, but it didn’t go anywhere. FWIW +1 to this as well as the ability to use multiple trailing closures like so:<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">animate(identifier: “”, duration: 0, update: {</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>// update</div><div class="gmail_msg">}, completion: {</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>// completion</div><div class="gmail_msg">}</div><div class="gmail_msg"><div class="gmail_msg"><br class="m_-994319049499522620Apple-interchange-newline gmail_msg"><span style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">Saagar Jha</span><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:&#39;SF UI Text&#39;;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"></div><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Jan 4, 2017, at 6:25 PM, Jay Abbott via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-994319049499522620Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="m_-994319049499522620markdown-here-wrapper gmail_msg"><p style="margin:0px 0px 1.2em!important" class="gmail_msg">When you have a function with a closure and then another optional default<span class="m_-994319049499522620Apple-converted-space gmail_msg"> </span><code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;display:inline" class="gmail_msg">= nil</code><span class="m_-994319049499522620Apple-converted-space gmail_msg"> </span>closure at the end, like this:</p><pre style="font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px" class="gmail_msg"><code class="m_-994319049499522620language-swift m_-994319049499522620hljs gmail_msg" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;white-space:pre-wrap;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em;color:rgb(51,51,51);background-image:none;background-color:rgb(248,248,248);display:block!important;background-position:0% 0%;background-repeat:repeat repeat">open <span class="m_-994319049499522620hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">static</span> <span class="m_-994319049499522620hljs-func gmail_msg"><span class="m_-994319049499522620hljs-keyword gmail_msg" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="m_-994319049499522620hljs-title gmail_msg" style="color:rgb(153,0,0);font-weight:bold">animate</span><span class="m_-994319049499522620hljs-params gmail_msg">(identifier: String,
                         duration: Double,
                         update: @escaping AnimationUpdate,
                         completion: AnimationCompletion? = <span class="m_-994319049499522620hljs-built_in gmail_msg" style="color:rgb(0,134,179)">nil</span>)</span> </span>{
</code></pre><p style="margin:0px 0px 1.2em!important" class="gmail_msg">You can’t use trailing closure syntax for the<span class="m_-994319049499522620Apple-converted-space gmail_msg"> </span><code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;display:inline" class="gmail_msg">update</code><span class="m_-994319049499522620Apple-converted-space gmail_msg"> </span>argument when leaving the<span class="m_-994319049499522620Apple-converted-space gmail_msg"> </span><code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;display:inline" class="gmail_msg">completion</code><span class="m_-994319049499522620Apple-converted-space gmail_msg"> </span>argument out/default.</p><p style="margin:0px 0px 1.2em!important" class="gmail_msg">This kind of breaks one of the benefits of default arguments, which is that you can add them to existing released functions without breaking the calling code. This means you have to add a separate convenience function without the extra argument, which is annoying and inelegant.</p></div></div></div></blockquote></div></div></div></blockquote><div style="font-family:SFUIText-Regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">Why not simply add the &quot;completion&quot; parameter before the trailing closure? That would still allow existing callers to work, without having to change the language. </div><br style="font-family:SFUIText-Regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><blockquote type="cite" style="font-family:SFUIText-Regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="m_-994319049499522620markdown-here-wrapper gmail_msg"><p style="margin:0px 0px 1.2em!important" class="gmail_msg">Another annoying thing is that you can easily miss this error if you happen to not use trailing closure syntax in your tests or other usage, because adding the extra default argument compiles fine for code that uses normal syntax.</p></div></div></div></blockquote></div></div></div></blockquote><div style="font-family:SFUIText-Regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg">The Swift compiler warns when a parameter written as a closure type isn&#39;t the last parameter. The warning is actually disabled in the specific case above because you&#39;ve written it using a typealias... maybe we should warn on such cases (it&#39;s worth a bug report). Regardless, in the majority of instances, you&#39;ll get a warning, so it won&#39;t be silent on disabling trailing closure syntax. </div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Tried this out in the playground:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">func foo(a: () -&gt; (), b: (() -&gt; ())? = nil) {</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>a()</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>b?()</div><div class="gmail_msg">}</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">foo(a: {</div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>print(“Bar”)</div><div class="gmail_msg">})</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">and didn’t receive a warning for it, either.</div></div></div></div></blockquote></div><br class="gmail_msg"><div class="gmail_msg">We don’t warn here because ‘foo’ does have a trailing closure… it’s for the second parameter. I guess we could still warn about ‘a’ (maybe lump it into the same bug about the typealias case).</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><span class="m_-994319049499522620Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>- Doug</div><div class="gmail_msg"><br class="gmail_msg"></div></div></div></blockquote></div><br class="gmail_msg"></div></div></div></blockquote></div><br class="gmail_msg"></div></blockquote></div>