<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=""><div class="">Sorry for answering this late, but I think this is a great proposal and would like to see especially the `foo(_)` syntax up for review, as it came up twice already while Doug Gregor and I discussed the implementation of getters and setters for #selector (<a href="https://bugs.swift.org/browse/SR-1239?focusedCommentId=13980&amp;#comment-13980" class="">here</a>&nbsp;and&nbsp;<a href="https://github.com/apple/swift-evolution/pull/280" class="">here</a>) and the upcoming proposal for disallowing arbitrary expressions inside #selector (<a href="https://github.com/ahoppen/swift-evolution/blob/arbitrary-expressions-in-selectors/proposals/0000-arbitrary-expressions-in-selectors.md" class="">Link to proposal</a>). I think not being able to reference an overloaded method without parameters without using `as` to disambiguate by type is a major hole in the type system.&nbsp;</div><div class=""><br class=""></div><div class="">Some comments inline.&nbsp;</div><div class=""><br class=""></div><blockquote type="cite" class="">This is another reaction to&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0066-standardize-function-type-syntax.md" class="">SE-0066</a>&nbsp;to which I'm mildly against.<div class=""><br class=""></div><div class="">I'd like to propose the following language changes to simplify function types and clarify what a function's name is. What gets removed is already ambiguous. And what is added makes higher-level programming with functions considerably simpler than currently. Furthermore, the proposed change considerably limits what constitutes the overload set of a function, which probably also speeds up the compilation process.</div><div class=""><br class=""></div><div class="">Let's consider the following declarations:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// #1&nbsp;</font></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">Function named&nbsp;'<b class="">foo(_)</b>' with type '<b class="">() -&gt; ()</b>'.</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(x: Int) -&gt; Int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// #2&nbsp;</font></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">Function named&nbsp;'<b class="">foo(x:)</b>' with type '<b class="">Int -&gt; Int</b>' (not an overload).</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(_ x: Int) -&gt; Int &nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// #3&nbsp;</font></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">Function named&nbsp;'<b class="">foo(_:)</b>' with type '<b class="">Int -&gt; Int</b>'</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(_ x: (Int, Int)) -&gt; Int&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// #4 Function named '<b class="">foo(_:)</b>' with type '<b class="">(Int, Int) -&gt; Int</b>' (overload of #3).</font></font></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(x: Int, y: Int) -&gt; Int &nbsp;</span><font color="#919191" class="" style="font-family: Menlo; font-size: 11px;">// #5 Function named '<b class="">foo(x:y:)</b>' with type '<b class="">(Int, Int) -&gt; Int</b>'.</font></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(x: Int, y: Int) -&gt; Bool&nbsp;</span><font color="#919191" class="" style="font-family: Menlo; font-size: 11px;">// #6 Function named '<b class="">foo(x:y:)</b>' with type '<b class="">(Int, Int) -&gt; Bool</b>' (overload of #5).</font></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;</span><font color="#ff2600" class="" style="font-family: Menlo; font-size: 11px;"><b class="">let</b>&nbsp;foo: Int</font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//&nbsp;<b class="">error:</b>&nbsp;invalid redeclaration of 'foo' (previously declared as a function)</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;baz: (Int, Int) -&gt; Int &nbsp; &nbsp; &nbsp;&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// #7 Variable named '<b class="">baz</b>' with type '<b class="">(Int, Int) -&gt; Int</b>'.</font></font></div></div><div class=""><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;</span><b class="" style="font-family: Menlo; font-size: 11px;">class</b><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;Bar {</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><b class="" style="font-family: Menlo; font-size: 11px;">func</b><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;baz() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #8 Method named '</span><b class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">Bar.baz(_)</b><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">' with type '<b class="">Bar -&gt; () -&gt; ()</b>'.</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><b class="" style="font-family: Menlo; font-size: 11px;">func</b><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;baz(x y: Int) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #9 Method named '</span><b class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">Bar.baz(x:)</b><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">' with type '<b class="">Bar -&gt; Int -&gt; ()</b>'.</span></div><div class=""><span class="" style="font-size: 11px; font-family: Menlo;">&nbsp; &nbsp; &nbsp; &nbsp;</span><span class="" style="font-size: 11px; font-family: Menlo;">&nbsp;</span><b class="" style="font-size: 11px; font-family: Menlo;">static func</b><span class="" style="font-size: 11px; font-family: Menlo;">&nbsp;</span><span class="" style="font-size: 11px; font-family: Menlo;">baz(x: Int = 0) &nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #10 Static method named '</span><b class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">Bar.Self.baz(x:)</b><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">' with type '<b class="">Int -&gt; ()</b>'.</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp; }</span></div></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<font color="#ff2600" class=""><b class="">let</b>&nbsp;f1</font></span><span class="" style="font-family: Menlo; font-size: 11px;"><font color="#ff2600" class="">&nbsp;= foo</font><font color="#919191" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//&nbsp;<b class="">error:</b>&nbsp;not a function reference, did you mean 'foo(_)'?</font></span></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<font color="#ff2600" class=""><b class="">let</b>&nbsp;f2</font><font color="#ff2600" class="">&nbsp;= foo&nbsp;<b class="">as</b>&nbsp;() -&gt; ()</font>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></font><font color="#919191" class="" style="font-family: Menlo; font-size: 11px;">//&nbsp;<b class="">error:</b>&nbsp;not a function reference, did you mean 'foo(_)'?</font></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f3</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;= foo(_) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #11 Function reference to #1. Has type '<b class="">() -&gt; ()</b>'.</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f4 = foo(x:) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #12 Function reference to #2.</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">Has type '<b class="">Int -&gt; Int</b>'.</span></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<font color="#ff2600" class=""><b class="">let</b>&nbsp;f5</font><font color="#ff2600" class="">&nbsp;= foo(_:)</font>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></font><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">//&nbsp;<b class="">error:</b>&nbsp;ambiguous function reference. Could be 'Int -&gt; Int' or '(Int, Int) -&gt; Int'</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f6</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;= foo(_:)&nbsp;<b class="">as</b>&nbsp;Int -&gt; Int &nbsp;&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #13 Function reference to #3. Has type '<b class="">Int -&gt; Int</b>'.</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f7</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;= foo(_:)&nbsp;<b class="">as</b>&nbsp;(Int, Int) -&gt; Int&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #14 Function reference to #4. Has type '<b class="">(Int, Int) -&gt; Int</b>'.</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;x1: Int</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;= foo(x:y:)(1, 2) &nbsp; &nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #15 Function application of #5. Picks the right overload by explicit return type.</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;x2: Bool</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;= foo(x:y:)((1, 2))&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #16 Function application of #6. Allowing a tuple here causes no ambiguity.</span></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f9 = baz &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></font><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #17 Function reference synonymous to #7. Has type&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">'</span><b class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">(Int, Int) -&gt; Int</b><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">'.</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;bar = Bar()</span></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><font color="#ff2600" face="Menlo" class="" style="font-size: 11px;"><b class="">let</b>&nbsp;f10 = bar.baz</font><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></font><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">//&nbsp;<b class="">error:</b>&nbsp;not a function reference, did you mean 'bar.baz(_)' or 'bar.baz(x:)'?</span></div><div class=""><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f11 = bar.baz(_) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #18 Function synonymous to the closure '{ bar.baz() }' with type '<b class="">() -&gt; ()</b>'.</span></div></div><div class=""><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f12 = bar.baz(x:) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// #19 Function synonymous to the closure '{ bar.baz(x: $0) }' with type '<b class="">Int -&gt; ()</b>'.</span></div></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp; let f13 = Bar.Self.baz(x:) &nbsp; &nbsp; &nbsp;&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// #20 Function synonymous to the closure '{ Bar.baz(x: $0) }' with type '</font><b class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">Int -&gt; ()</b><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">'.</span></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp; let f14 = Bar.Self.baz(_) &nbsp; &nbsp; &nbsp; &nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// #21 Function synonymous to the closure '{ Bar.baz() }' with type '<b class="">() -&gt; ()</b>'.</font></div><div class=""><br class=""></div><div class="">The following list of proposed changes sum up what's new above.</div><div class=""><br class=""></div><div class="">C1: Extend&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md" class="">SE-0021</a>&nbsp;by&nbsp;<b class="">adding</b>&nbsp;the underscore-in-parentheses syntax `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo(_)</span></font>` to refer to the zero-argument function #1.</div></blockquote><div class=""><br class=""></div><div class="">A huge +10 on this one as it stands. I think in the context of functions the underscore already has a meaning of "there is nothing" as in the parameter names. The only possible issue I see is whether we may end up in a conflict should we ever decide for functions to have out-only parameters that you may ignore by passing "_" as argument. But I don't see this coming. Only opinions from the core team?</div><br class=""><blockquote type="cite" class=""><div class="">C2: Extend&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md" class="">SE-0021</a>&nbsp;by&nbsp;<b class="">removing</b>&nbsp;the ambiguity between instance and type members. From now on, `Bar.baz(_)`&nbsp;</div></blockquote><div class=""><br class=""></div><div class="">I’m slightly opposed to this one. I, for my part, would expect `Bar.baz(_)` to refer to the static function instead of `Bar`, since nothing in this name suggests a instance methods. The fact that you can access instance methods on a type as `(Type) -&gt; (Args) -&gt; ReturnValue` has always seem more like magic to me.</div><br class=""><blockquote type="cite" class=""><div class="">C3: Extend&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md" class="">SE-0021</a>&nbsp;by&nbsp;<b class="">banning</b>&nbsp;the use of&nbsp;<i class="">base name only</i>&nbsp;to refer to a function, i.e. neither `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo</span></font>` nor `<font face="Menlo" class=""><span class="" style="font-size: 11px;">Bar.baz</span></font>` can be used to refer to refer to any of #1–#6 or #8–#10.</div></blockquote><div class=""><br class=""></div><div class="">I think this is largely impacted by the future direction of Swift on whether argument names are counted as part of a function’s name or not. I think they currently aren’t but if I recall correctly there are thought to change this. If this is the case, removing the option to use `foo` to refer to `foo(x:)` or `foo(_)` would only make sense from my point of view and should be done in the Swift 3 timeframe as a source breaking change. Otherwise I see no point in removing the option to reference a method by its base name, because technically speaking, it’s simply its name.&nbsp;</div><div class="">Could maybe someone of the core team comment on the future direction, Swift should take?</div><br class=""><blockquote type="cite" class=""><div class="">C4: Extend&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md" class="">SE-0021</a>&nbsp;to&nbsp;<b class="">allow</b>&nbsp;the selective omission of defaulted arguments, e.g. `<font face="Menlo" class=""><span class="" style="font-size: 11px;"><b class="">let</b>&nbsp;f = print(_:separator:)</span></font>` creates the function variable `<font face="Menlo" class=""><span class="" style="font-size: 11px;">f: (Any, String) -&gt; ()</span></font>` equivalent to `<font face="Menlo" class=""><span class="" style="font-size: 11px;">{ print($0, separator: $1) }</span></font>`.</div></blockquote><div class=""><br class=""></div><div class="">Sounds very reasonable to me. Especially, I think the idea of creating a new function that simply forwards to the original function solves the problem of handling unspecified default parameters very elegantly.&nbsp;</div><div class="">At first I was worried about the additional indirection and its potential performance implications, but functions with default parameters already dispatch another function call for each argument anyway, so this shouldn’t be a problem.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class="">C5:&nbsp;<b class="">Clarify</b>&nbsp;the language specification by stating that&nbsp;<b class="">functions with different labels</b>&nbsp;(e.g. `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo(_:)</span></font>` vs. `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo(x:)</span></font>`)&nbsp;<b class="">are not&nbsp;overloads&nbsp;</b>of each other. Instead, two functions are considered overloads of each other if only if they have matching base names (e.g. `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo</span></font>`) and matching argument labels (e.g. `<font face="Menlo" class=""><span class="" style="font-size: 11px;">(x:y:)</span></font>`) but differing argument or return types (e.g. #3 and #4, or #5 and #6).</div></blockquote><div class=""><br class=""></div><div class="">AFAIK, currently they are. See my comment on C3 for this.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class="">C6:&nbsp;<b class="">Clarify</b>&nbsp;that by using the base name `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo</span></font>` for a function, the same scope cannot define a variable with the name `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo</span></font>`. And, vice versa, in a scope that defines a variable named `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo</span></font>`, there can be no function `<font face="Menlo" class=""><span class="" style="font-size: 11px;">foo(...)</span></font>` defined at the same scope level.</div></blockquote><div class=""><br class=""></div><div class="">Again implied by the decision on whether arguments (and their names) are counted as part of the function’s signature or not.</div><br class=""><blockquote type="cite" class=""><div class="">The implications are:</div><div class=""><br class=""></div><div class="">I1: The use of a function's base name to refer to a function will cease to work. It has, however, been buggy up to this date. Consider the following:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f = [Int].prefix&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;'</font></font></div><div class=""><font face="Menlo" class=""><font color="#919191" class="" style="font-size: 11px;"><br class=""></font></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;g1 = [Int].dropFirst&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// Inexplicably chooses the '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;' overload!</font></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;g2 = [Int].dropFirst&nbsp;<b class="">as</b>&nbsp;[Int] -&gt; () -&gt; ArraySlice&lt;Int&gt;&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// Disambiguate</font><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">&nbsp;</span><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">by type</span><span class="" style="font-size: 11px; color: rgb(145, 145, 145); font-family: Menlo;">.</span></div><div class=""><font color="#919191" face="Menlo" class="" style="font-size: 11px;"><br class=""></font></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;h1 = [Int].sorted&nbsp;</span><font color="#919191" class="" style="font-family: Menlo; font-size: 11px;">// Chooses the '[Int] -&gt; () -&gt; [Int]' overload, unlike 'dropFirst' above.</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;h2 = [Int].sorted&nbsp;<b class="">as</b>&nbsp;[Int] -&gt; ((Int, Int) -&gt; Bool) -&gt; [Int]&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// Disambiguate by type.</font></div></div><div class=""><br class=""></div><div class="">With the proposed changes, the above becomes:</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f = [Int].prefix(_:) &nbsp; &nbsp;&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;'</font></font></div><div class=""><font face="Menlo" class=""><font color="#919191" class="" style="font-size: 11px;"><br class=""></font></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;g1 = [Int].dropFirst(_:)&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;'</font></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;g2 = [Int].dropFirst(_) &nbsp;</span></font><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// '[Int] -&gt; () -&gt; ArraySlice&lt;Int&gt;'</span></div><div class=""><font color="#919191" face="Menlo" class="" style="font-size: 11px;"><br class=""></font></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;h1 = [Int].sorted(_) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" class="" style="font-family: Menlo; font-size: 11px;">// '[Int] -&gt; () -&gt; [Int]'</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;h2 = [Int].sorted(isOrderedBefore:)&nbsp;</span></font><span class="" style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;">// '[Int] -&gt; ((Int, Int) -&gt; Bool) -&gt; [Int]'</span></div></div></div><div class=""><font color="#919191" face="Menlo" class="" style="font-size: 11px;"><br class=""></font></div><div class="">I2: When referring to functions the&nbsp;<b class="">argument labels disappear</b>&nbsp;in the returned function. That's a good thing because there's no generic way to call functions with arguments, and that's why closures too always come without argument labels. We don't, however, lose any clarity at the point where the function reference is passed as an argument because function references always contain the labels in the new notation. (Also, see the future directions for an idea how argument labels can be restored in the function variable.)</div></blockquote><div class=""><br class=""></div><div class="">I can’t really see where this implication comes from and I’m strongly against it. I wouldn’t expect value of a variable to change just because I assign it to a new variable. Neither would I want my function’s signature to change just because I assign the function to another variable.&nbsp;</div><div class="">I rather think that it’s a missing feature that closures cannot have named arguments, but that’s orthogonal to this proposal.</div><br class=""><blockquote type="cite" class=""><div class="">I3: Function argument lists are no longer that special and there's no need to notate single-n-tuple argument lists separately from n-argument functions, i.e.&nbsp;<b class=""><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0066-standardize-function-type-syntax.md" class="">SE-0066</a>&nbsp;is not really needed anymore</b>. The new intuition here is that&nbsp;<b class="">it's the function's name that defines how a function can be called</b>, not its type.</div></blockquote><div class=""></div><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><div class="">I4: Because function variables cannot be overloaded, we can without ambiguity allow all of the following "tuple splatting":</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;tuple1 = (1, 2)</span></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;tuple2 = (x: 1, y: 2)</span></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;tuple3 = (a: 1, b: 2)</span></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span><b class="" style="font-size: 11px;">let</b><span class="" style="font-size: 11px;">&nbsp;y1 = foo(tuple1) &nbsp; &nbsp; &nbsp;&nbsp;</span><font color="#919191" class="" style="font-size: 11px;">// Not a "tuple splat", calls #4 as normal.</font></font></div><div class=""><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;y2 = foo(tuple2)</span></font><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// Not a "tuple splat", calls #4 as normal.</font></div></div><div class=""><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;y3 = foo(tuple3)</span></font><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// Not a "tuple splat", calls #4 as normal.</font></div></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;y4 = foo(_:)(1, 2) &nbsp; &nbsp;&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// Not a "tuple splat", calls the reference to #4 as normal.</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;y5 = foo(_:)((1, 2)) &nbsp;&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// "Tuple splat", calls #4.</font></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;y6 = foo(_:)(((1, 2)))&nbsp;<font color="#919191" class="">//&nbsp;</font></span><font color="#919191" class=""><span class="" style="font-family: Menlo; font-size: 11px;">"Tuple splat", calls #4.</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px;">Nothing special here, just an unnecessary pair of parens.</span></font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;y7 = foo(_:)(tuple1) &nbsp;&nbsp;<font color="#919191" class="">//&nbsp;</font><font color="#919191" class="">"Tuple splat", calls #4.</font></span></font></div><div class=""><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;y8 = foo(_:)(tuple2) &nbsp;&nbsp;<font color="#919191" class="">//&nbsp;</font><font color="#919191" class="">"Tuple splat", calls #4. The labelled tuple type is compatible with '(Int, Int)'.</font></span></font></div></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;z1 = foo(x:y:)(tuple1)&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">as</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;Int&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// "Tuple splat", calls #5 because the return type is explicitly 'Int'.</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;z2 = foo(x:y:)(tuple2)&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">as</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;Int&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// "Tuple splat", calls #5. The labels don't really matter here.</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;z3 = foo(x:y:)(tuple3)&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">as</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;Int&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// "Tuple splat", calls #5. Like above, any tuple labels are compatible in the call.</font></div><div class=""><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; &nbsp;&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">let</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;z4 = (foo(x:y:)&nbsp;</span></font><b class="" style="font-family: Menlo; font-size: 11px;">as</b><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;(Int, Int) -&gt; Bool)(tuple3)&nbsp;</span></font><font color="#919191" face="Menlo" class="" style="font-size: 11px;">// Here's another way to explicitly pick up the overload.</font></div></blockquote><div class=""><br class=""></div>All function arguments used to be one tuple, but it turned out that certain features (inout params and varargs, if i recall correctly) cannot be handled if a function is considered as only taking one tuple as an argument. Tuple splatting was removed because it didn’t fit into the language naturally anymore.<div class=""><br class=""><div class="">– Alex</div></div><div class=""><br class=""></div></div></body></html>