<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" 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 style="font-size: 11px;" class="">&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" style="font-size: 11px;" class="">// #1&nbsp;</font></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">Function named&nbsp;'<b class="">foo(_)</b>' with type '<b class="">() -&gt; ()</b>'.</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(x: Int) -&gt; Int &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// #2&nbsp;</font></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">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 style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(_ x: Int) -&gt; Int &nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// #3&nbsp;</font></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">Function named&nbsp;'<b class="">foo(_:)</b>' with type '<b class="">Int -&gt; Int</b>'</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(_ x: (Int, Int)) -&gt; Int&nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// #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 style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(x: Int, y: Int) -&gt; Int &nbsp;</span><font color="#919191" style="font-family: Menlo; font-size: 11px;" class="">// #5 Function named '<b class="">foo(x:y:)</b>' with type '<b class="">(Int, Int) -&gt; Int</b>'.</font></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">func</b>&nbsp;foo(x: Int, y: Int) -&gt; Bool&nbsp;</span><font color="#919191" style="font-family: Menlo; font-size: 11px;" class="">// #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 style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;</span><font color="#ff2600" style="font-family: Menlo; font-size: 11px;" class=""><b class="">let</b>&nbsp;foo: Int</font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// <b class="">error:</b> invalid redeclaration of 'foo' (previously declared as a function)</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;baz: (Int, Int) -&gt; Int &nbsp; &nbsp; &nbsp;&nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// #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 style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;</span><b style="font-family: Menlo; font-size: 11px;" class="">class</b><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;Bar {</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><b style="font-family: Menlo; font-size: 11px;" class="">func</b><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;baz() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #8 Method named '</span><b style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">Bar.baz(_)</b><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">' with type '<b class="">Bar -&gt; () -&gt; ()</b>'.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><b style="font-family: Menlo; font-size: 11px;" class="">func</b><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;baz(x y: Int) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #9 Method named '</span><b style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">Bar.baz(x:)</b><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">' with type '<b class="">Bar -&gt; Int -&gt; ()</b>'.</span></div><div class=""><span style="font-size: 11px; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="font-size: 11px; font-family: Menlo;" class="">&nbsp;</span><b style="font-size: 11px; font-family: Menlo;" class="">static func</b><span style="font-size: 11px; font-family: Menlo;" class="">&nbsp;</span><span style="font-size: 11px; font-family: Menlo;" class="">baz(x: Int = 0) &nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #10 Static method named '</span><b style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">Bar.Self.baz(x:)</b><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">' with type '<b class="">Int -&gt; ()</b>'.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; }</span></div></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <font color="#ff2600" class=""><b class="">let</b> f1</font></span><span style="font-family: Menlo; font-size: 11px;" class=""><font color="#ff2600" class="">&nbsp;= foo</font><font color="#919191" class="">&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 style="font-size: 11px;" class="">&nbsp; &nbsp; <font color="#ff2600" class=""><b class="">let</b> f2</font><font color="#ff2600" class="">&nbsp;= foo <b class="">as</b> () -&gt; ()</font> &nbsp; &nbsp; &nbsp; &nbsp; </span></font><font color="#919191" style="font-family: Menlo; font-size: 11px;" class="">// <b class="">error:</b>&nbsp;not a function reference, did you mean 'foo(_)'?</font></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f3</span><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;= foo(_) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #11 Function reference to #1. Has type '<b class="">() -&gt; ()</b>'.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f4 = foo(x:) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #12 Function reference to #2.</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">Has type '<b class="">Int -&gt; Int</b>'.</span></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <font color="#ff2600" class=""><b class="">let</b> f5</font><font color="#ff2600" class="">&nbsp;= foo(_:)</font> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></font><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// <b class="">error:</b>&nbsp;ambiguous function reference. Could be 'Int -&gt; Int' or '(Int, Int) -&gt; Int'</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f6</span><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;= foo(_:) <b class="">as</b> Int -&gt; Int &nbsp;&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #13 Function reference to #3. Has type '<b class="">Int -&gt; Int</b>'.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f7</span><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;= foo(_:) <b class="">as</b> (Int, Int) -&gt; Int&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #14 Function reference to #4. Has type '<b class="">(Int, Int) -&gt; Int</b>'.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> x1: Int</span><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;= foo(x:y:)(1, 2) &nbsp; &nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #15 Function application of #5. Picks the right overload by explicit return type.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> x2: Bool</span><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;= foo(x:y:)((1, 2)) </span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #16 Function application of #6. Allowing a tuple here causes no ambiguity.</span></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f9 = baz &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></font><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #17 Function reference synonymous to #7. Has type&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">'</span><b style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">(Int, Int) -&gt; Int</b><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">'.</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> bar = Bar()</span></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span></font><font color="#ff2600" face="Menlo" style="font-size: 11px;" class=""><b class="">let</b> f10 = bar.baz</font><font face="Menlo" class=""><span style="font-size: 11px;" class=""> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></font><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// <b class="">error:</b> not a function reference, did you mean 'bar.baz(_)' or 'bar.baz(x:)'?</span></div><div class=""><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f11 = bar.baz(_) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #18 Function synonymous to the closure '{ bar.baz() }' with type '<b class="">() -&gt; ()</b>'.</span></div></div><div class=""><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f12 = bar.baz(x:) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// #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 style="font-size: 11px;" class="">&nbsp; &nbsp; let f13 = Bar.Self.baz(x:) &nbsp; &nbsp; &nbsp; </span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// #20 Function synonymous to the closure '{ Bar.baz(x: $0) }' with type '</font><b style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">Int -&gt; ()</b><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">'.</span></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; let f14 = Bar.Self.baz(_) &nbsp; &nbsp; &nbsp; &nbsp;</span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// #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 <b class="">adding</b>&nbsp;the underscore-in-parentheses syntax `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo(_)</span></font>` to refer to the zero-argument function #1.</div><div class=""><br class=""></div><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 <b class="">removing</b>&nbsp;the ambiguity between instance and type members. From now on, `Bar.baz(_)`&nbsp;</div><div class=""><br class=""></div><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 <b class="">banning</b> the use of <i class="">base name only</i> to refer to a function, i.e. neither `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo</span></font>` nor `<font face="Menlo" class=""><span style="font-size: 11px;" class="">Bar.baz</span></font>` can be used to refer to refer to any of #1–#6 or #8–#10.</div><div class=""><br class=""></div><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 <b class="">allow</b> the selective omission of defaulted arguments, e.g. `<font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">let</b> f = print(_:separator:)</span></font>` creates the function variable `<font face="Menlo" class=""><span style="font-size: 11px;" class="">f: (Any, String) -&gt; ()</span></font>` equivalent to `<font face="Menlo" class=""><span style="font-size: 11px;" class="">{ print($0, separator: $1) }</span></font>`.</div><div class=""><br class=""></div><div class="">C5: <b class="">Clarify</b> the language specification by stating that <b class="">functions with different labels</b> (e.g. `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo(_:)</span></font>` vs. `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo(x:)</span></font>`) <b class="">are not&nbsp;overloads </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 style="font-size: 11px;" class="">foo</span></font>`) and matching argument labels (e.g. `<font face="Menlo" class=""><span style="font-size: 11px;" class="">(x:y:)</span></font>`) but differing argument or return types (e.g. #3 and #4, or #5 and #6).</div><div class=""><br class=""></div><div class="">C6: <b class="">Clarify</b>&nbsp;that by using the base name `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo</span></font>` for a function, the same scope cannot define a variable with the name `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo</span></font>`. And, vice versa, in a scope that defines a variable named `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo</span></font>`, there can be no function `<font face="Menlo" class=""><span style="font-size: 11px;" class="">foo(...)</span></font>` defined at the same scope level.</div><div class=""><br class=""></div><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 style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f = [Int].prefix&nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;'</font></font></div><div class=""><font face="Menlo" class=""><font color="#919191" style="font-size: 11px;" class=""><br class=""></font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;g1 = [Int].dropFirst&nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// Inexplicably chooses the '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;' overload!</font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&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" style="font-size: 11px;" class="">// Disambiguate</font><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">&nbsp;</span><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">by type</span><span style="font-size: 11px; color: rgb(145, 145, 145); font-family: Menlo;" class="">.</span></div><div class=""><font color="#919191" face="Menlo" style="font-size: 11px;" class=""><br class=""></font></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;h1 = [Int].sorted&nbsp;</span><font color="#919191" style="font-family: Menlo; font-size: 11px;" class="">// Chooses the '[Int] -&gt; () -&gt; [Int]' overload, unlike 'dropFirst' above.</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;</span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class="">&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" style="font-size: 11px;" class="">// 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 style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;f = [Int].prefix(_:) &nbsp; &nbsp;&nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;'</font></font></div><div class=""><font face="Menlo" class=""><font color="#919191" style="font-size: 11px;" class=""><br class=""></font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;g1 = [Int].dropFirst(_:)&nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// '[Int] -&gt; Int -&gt; ArraySlice&lt;Int&gt;'</font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;g2 = [Int].dropFirst(_) &nbsp;</span></font><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// '[Int] -&gt; () -&gt; ArraySlice&lt;Int&gt;'</span></div><div class=""><font color="#919191" face="Menlo" style="font-size: 11px;" class=""><br class=""></font></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;<b class="">let</b>&nbsp;h1 = [Int].sorted(_) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" style="font-family: Menlo; font-size: 11px;" class="">// '[Int] -&gt; () -&gt; [Int]'</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;</span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;h2 = [Int].sorted(isOrderedBefore:)&nbsp;</span></font><span style="color: rgb(145, 145, 145); font-family: Menlo; font-size: 11px;" class="">// '[Int] -&gt; ((Int, Int) -&gt; Bool) -&gt; [Int]'</span></div></div></div><div class=""><font color="#919191" face="Menlo" style="font-size: 11px;" class=""><br class=""></font></div><div class="">I2: When referring to functions the <b class="">argument labels disappear</b> 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><div class=""><br class=""></div><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 <b class="">it's the function's name that defines how a function can be called</b>, not its type.</div><div class=""><br class=""></div><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 style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> tuple1 = (1, 2)</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> tuple2 = (x: 1, y: 2)</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> tuple3 = (a: 1, b: 2)</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span><b style="font-size: 11px;" class="">let</b><span style="font-size: 11px;" class=""> y1 = foo(tuple1) &nbsp; &nbsp; &nbsp; </span><font color="#919191" style="font-size: 11px;" class="">// Not a "tuple splat", calls #4 as normal.</font></font></div><div class=""><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> y2 = foo(tuple2)</span></font><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// Not a "tuple splat", calls #4 as normal.</font></div></div><div class=""><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> y3 = foo(tuple3)</span></font><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// Not a "tuple splat", calls #4 as normal.</font></div></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""> y4 = foo(_:)(1, 2) &nbsp; &nbsp; </span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// Not a "tuple splat", calls the reference to #4 as normal.</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""> y5 = foo(_:)((1, 2)) &nbsp; </span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// "Tuple splat", calls #4.</font></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> y6 = foo(_:)(((1, 2))) <font color="#919191" class="">//&nbsp;</font></span><font color="#919191" class=""><span style="font-family: Menlo; font-size: 11px;" class="">"Tuple splat", calls #4.</span><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;</span><span style="font-family: Menlo; font-size: 11px;" class="">Nothing special here, just an unnecessary pair of parens.</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""> y7 = foo(_:)(tuple1) &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 style="font-size: 11px;" class="">&nbsp; &nbsp; </span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""> y8 = foo(_:)(tuple2) &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 style="font-size: 11px;" class="">&nbsp; &nbsp; </span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""> z1 = foo(x:y:)(tuple1) </span></font><b style="font-family: Menlo; font-size: 11px;" class="">as</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""> Int </span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// "Tuple splat", calls #5 because the return type is explicitly 'Int'.</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;</span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;z2 = foo(x:y:)(tuple2)&nbsp;</span></font><b style="font-family: Menlo; font-size: 11px;" class="">as</b><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;Int </span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// "Tuple splat", calls #5. The labels don't really matter here.</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;</span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;z3 = foo(x:y:)(tuple3)&nbsp;</span></font><b style="font-family: Menlo; font-size: 11px;" class="">as</b><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;Int </span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// "Tuple splat", calls #5. Like above, any tuple labels are compatible in the call.</font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span></font><b style="font-family: Menlo; font-size: 11px;" class="">let</b><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;z4 = (foo(x:y:) </span></font><b style="font-family: Menlo; font-size: 11px;" class="">as</b><font face="Menlo" class=""><span style="font-size: 11px;" class=""> (Int, Int) -&gt; Bool)(tuple3) </span></font><font color="#919191" face="Menlo" style="font-size: 11px;" class="">// Here's another way to explicitly pick up the overload.</font></div><div class=""><br class=""></div><div class=""><b class="">Future directions</b></div><div class=""><br class=""></div><div class="">F1: In this proposal, I made a difference between function identifier names and variable identifier names. However, it could be well allowed to use function-like names for function variables when clarity is needed. Then calling a block would require the argument labels just like functions:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> <font color="#9929bd" class="">block(value:)</font> = {value <b class="">in</b> ...}</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; block(value: 1)</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""><br class=""></span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">func</b> foo(_ <font color="#9929bd" class="">isOrderedBefore(lhs:rhs:)</font>: (Int, Int) -&gt; Bool) {</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; let x = isOrderedBefore(lhs: 1, rhs: 2)</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; }</span></font></div><div class=""><br class=""></div><div class="">F2: The following idea probably divides opinions, but because function variables are unambiguous, we could even allow calling them <i class="">without</i> parentheses like in Haskell. That would open up many doors to currying and building highly composable functional libraries:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">let</b> f = {x <b class="">in</b> ...}</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span><b style="font-size: 11px;" class="">let</b><span style="font-size: 11px;" class=""> y = f 1 </span><font color="#919191" style="font-size: 11px;" class="">// calls 'f' with an 'Int'</font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span><b style="font-size: 11px;" class="">let</b><span style="font-size: 11px;" class=""> z = f (1, 2) </span><font color="#919191" style="font-size: 11px;" class="">// calls 'f' with an '(Int, Int)'</font></font></div><div class=""><br class=""></div><div class="">F3: And if that was allowed, maybe it could be possible to define functions with variable-like names and currying too, but now I'm getting too far. I think the proposal is worth considering even if we never go to the direction of Haskell in this way.</div><div class=""><br class=""></div><div class="">— Pyry</div><div class=""><br class=""></div></body></html>