Hmm, I don&#39;t recall the earlier discussion, but IMO, Charlie&#39;s proposal is pretty sensible. Seems backwards to adding much broader things like default argument support for protocols motivated by a use case that should Just Work(TM).<br><br>I recall that once upon a time Chris Lattner declared that the core team was perfectly willing to implement difficult things if it improved the Swift user experience. Here, it seems either this is something that *can* be made to just work in the default arguments handling department, and then it should be, or it can&#39;t, and then the closure syntax is a fairly obvious and workable if not pretty workaround. No point in designing features as a workaround for something that has both an obvious ideal solution and a current workaround.<br><div class="gmail_quote"><div dir="ltr">On Thu, Jan 19, 2017 at 23:07 David Sweeris via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">On Jan 9, 2017, at 02:13, Charlie Monroe 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" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I came across something that I&#39;m not sure it&#39;s a bug or by design and if it&#39;s by design, whether this should be discussed here.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Example:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">class</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> Foo {</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">init</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(number: </span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">) { </span><span style="font-variant-ligatures:no-common-ligatures;color:#008400" class="gmail_msg">/* ... */</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> }</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;min-height:10px" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"></span><br class="gmail_msg"></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> closure = </span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Foo</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">init</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(number:) </span><span style="font-variant-ligatures:no-common-ligatures;color:#008400" class="gmail_msg">// (Int) -&gt; Foo</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">[</span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">1</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">, </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">2</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">, </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">3</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">].</span><span style="font-variant-ligatures:no-common-ligatures;color:#3e1e81" class="gmail_msg">map</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">closure</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">) </span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">// [Foo, Foo, Foo]</span></div></div><div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg"></span></div><div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">This works great until the initializer gets a default argument:</span></div><div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg"></span></div><div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">class</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> Foo {</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">init</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(number: </span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, string: </span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">String</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> = </span><span style="font-variant-ligatures:no-common-ligatures;color:#d12f1b" class="gmail_msg">&quot;&quot;</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">) { </span><span style="font-variant-ligatures:no-common-ligatures;color:#008400" class="gmail_msg">/* ... */</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> }</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;min-height:10px" class="gmail_msg"><span style="color:rgb(0,132,0)" class="gmail_msg"><br class="gmail_msg"></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;min-height:10px" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"></span><span style="color:rgb(0,132,0)" class="gmail_msg">// Error: Foo has no member init(number:)</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"> closure = </span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Foo</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">init</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg">(number:) </span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><br class="gmail_msg"></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><span style="font-family:Helvetica;font-size:10px" class="gmail_msg">I was wondering if we could get closures to methods without the default arguments. Currently, this needs to be worked around by e.g. creating a second closure that invokes the method without the default arguments:</span></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><span style="font-family:Helvetica;font-size:10px" class="gmail_msg"><br class="gmail_msg"></span></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span> closure: (<span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">Int</span>) -&gt; <span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Foo</span> = { <span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Foo</span>(number: $0) }</span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><br class="gmail_msg"></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><span style="font-family:Helvetica;font-size:10px" class="gmail_msg">But to me it seems like something that should work &quot;out of the box&quot;.</span></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><span style="font-family:Helvetica;font-size:10px" class="gmail_msg"><br class="gmail_msg"></span></span></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><span style="font-family:Helvetica;font-size:10px" class="gmail_msg">Thoughts?</span></span></div></span></div></div></blockquote><br class="gmail_msg"></div><div dir="auto" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">IIRC, this issue was raised a while ago, and as best as I recall the gist of the answer was that default arguments are implemented at the call site, and because of that you can&#39;t pass a function with default arguments to something expecting a function with fewer arguments even though the two calls look identical in the source code.</span></div><span style="background-color:rgba(255,255,255,0)" class="gmail_msg"><br class="gmail_msg"></span><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">It causes other issues, too. For instance, if we have</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">    protocol Initable { init() }</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">And</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">    struct Foo { init(_ x: Int = 0) {} }</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">We&#39;re left in an odd situation where `Foo`  can&#39;t meaningfully conform to `Initable` because while &quot;init(_: Int = 0)&quot; is not the same as &quot;init()&quot;, if you add a &quot;init()&quot; to `Foo`</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">you&#39;ll get an ambiguous somethingerather error because there&#39;s no mechanism for the compiler to know whether you want the actual &quot;0 argument&quot; function or the &quot;1 argument with 1 default value&quot; function.</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg"><br class="gmail_msg"></span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">Aside from re-architecting the default argument system (which I&#39;m not even sure is possible, let alone a good idea), I think I see couple ways forward for the protocol conformance issue. Both have downsides, though.</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg"><br class="gmail_msg"></span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">1) Require any potentially conflicting protocol functions to be in an extension so the compiler knows what&#39;s going on, have &quot;Foo()&quot; call the one defined in the type, and use &quot;(Foo as Initable)()&quot; for the protocol version defined in an extension. This could get real confusing real fast if people don&#39;t realize there&#39;s two functions with, as far as they can tell, the same signature.</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg"><br class="gmail_msg"></span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">2) Add default argument support to protocols. The syntax that makes sense to me would be something like</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">    protocol Bar {</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">        func baz(_: Int = _)</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">    }</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">On the downside, I suspect this would necessarily add a phantom &quot;Self or associated type requirement&quot; so that the compiler could have a way to get at each implementation&#39;s default value. It&#39;s not ideal... You&#39;d get an error kinda out of the blue if you tried to use the function non-generically, but at least you couldn&#39;t have a function change out from under you.</span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg"><br class="gmail_msg"></span></div><div class="gmail_msg"><span style="background-color:rgba(255,255,255,0)" class="gmail_msg">- Dave Sweeris </span></div></div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>