<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="">On Apr 26, 2016, at 3:37 PM, Mishal Awadah &lt;<a href="mailto:a.mamish@gmail.com" class="">a.mamish@gmail.com</a>&gt; wrote:<br class=""><div><blockquote type="cite" class="">This analogy doesn’t exist in Swift, languages like Haskell have auto-currying behavior like this, but Swift does not.<br class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Indeed, my point is that this proposal drives the distance further from this analogy, which is a nice one, because function application is still relevant in Swift, and may be more so in the future. That is to say, this is closing a functional programming door. I am contrasting this proposal to Haskell's type system, not the existing Swift one, to increase the awareness of the direction this is going.&nbsp;</div></div></div></div></div></blockquote><div><br class=""></div><div>Hi Mish,</div><div><br class=""></div><div>I’m also fond of Haskell and the MLs, and I appreciate many of the choices that they made in the context of their languages. &nbsp;However, there are a large number of deep differences between the type system in Swift and the type system in Haskell that motivate the current behavior we have in Swift.</div><div><br class=""></div><div>SE-0066 is a very narrow proposal - it only affects syntax, not semantics. &nbsp;The type system semantics that you seem interested in are unlikely to happen regardless of the syntax changes SE-0066 imply, and SE-0066 doesn’t have anything to do with that.</div><div><br class=""></div><div>-Chris</div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">In summary: I am concerned that by doing this we will never do the Haskell-style type annotations, which feel more at home in Swift.&nbsp;</div><div class=""><br class=""></div><div class="">Obviously, if the Haskell-style annotations are a given "we are never going to adopt this in Swift", then I cannot argue with the increased clarity that 0066 provides, despite the unpleasant parenthesis proliferation it will cause.</div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span class=""><br class="">
&gt;<br class="">
&gt; This eliminates the ambiguity of what the parameter types are, and is more legible (less paren hell) than adding parens like this:<br class="">
&gt;<br class="">
&gt; (A,B) -&gt; C<br class="">
&gt;<br class="">
&gt; which for a function<br class="">
&gt;<br class="">
&gt; foo(a: (A, B)) -&gt; C<br class="">
&gt;<br class="">
&gt; would look like this after the implementation of SE-0066:<br class="">
&gt;<br class="">
&gt; ((A,B)) -&gt; C<br class="">
&gt;<br class="">
&gt; instead of<br class="">
&gt;<br class="">
&gt; (A,B) -&gt; C<br class="">
<br class="">
</span>I’m not sure what the actual concern you’re pointing out here.&nbsp; However, you are forgetting the argument labels.&nbsp; Your foo example will have type:<br class="">
<br class="">
(a: (A,B)) -&gt; C<br class="">
<br class="">
More to the point thought, this example is *exactly* why SE-0066 is the right thing to do.&nbsp; You cannot currently write the type of “foo” as "(A,B) -&gt; C”.&nbsp; (with or without labels), because of the grammar ambiguities that SE-0066 fixes.<br class="">
<br class="">
That said, it is likely that I’m totally missing your point here, can you please restate your concern?<br class="">
<span class=""><br class=""></span></blockquote><div class=""><br class=""></div><div class="">I'm confused, I created this function and got the type without argument label annotation.&nbsp;</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131);" class=""><span style="color:rgb(133,153,1)" class="">func</span><span style="" class=""> happy(a: (</span><span style="color:rgb(181,137,1)" class="">Int</span><span style="" class="">, </span><span style="color:rgb(181,137,1)" class="">Int</span><span style="" class="">)) -&gt; </span><span style="color:rgb(181,137,1)" class="">String</span><span style="" class=""> {</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(41, 161, 152);" class=""><span style="color:rgb(101,123,131)" class="">&nbsp; &nbsp; </span><span style="color:rgb(133,153,1)" class="">return</span><span style="color:rgb(101,123,131)" class=""> </span><span style="" class="">"Happy"</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131);" class=""><span style="" class="">}</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131); min-height: 16px;" class=""><span style="" class=""></span><br class=""></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(133, 153, 1);" class=""><span style="color:rgb(108,113,196)" class="">print</span><span style="color:rgb(101,123,131)" class="">(</span><span style="color:rgb(108,113,196)" class="">happy</span><span style="color:rgb(101,123,131)" class="">.</span><span style="" class="">dynamicType</span><span style="color:rgb(101,123,131)" class="">)</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131); min-height: 16px;" class=""><span style="color:rgb(147,161,161)" class="">// prints: (Int, Int) -&gt; String</span><br class=""><span style="" class=""></span></div></div><div class="">&nbsp;</div><div class=""><br class=""></div><div class="">The concern is that rather than move towards a more Haskell-like syntax (which removes ambiguity of tuple params over multiple params as well) this is adding more parens and making it look less pleasant to read. Contrast the types of these functions in the Haskell-Style, and the proposed 0066 style:&nbsp;</div><div class=""><br class=""></div><div class="">Haskell Style: (Int, Int) -&gt; String</div><div class="">0066 Style: ((Int, Int)) -&gt; String</div><div class=""><br class=""></div><div class="">The Haskell Style would remove the ambiguity against a function like this:&nbsp;</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131);" class=""><span style="color:rgb(133,153,1)" class="">func</span><span style="" class=""> unhappy(a: </span><span style="color:rgb(181,137,1)" class="">Int</span><span style="" class="">, b: </span><span style="color:rgb(181,137,1)" class="">Int</span><span style="" class="">) -&gt; </span><span style="color:rgb(181,137,1)" class="">String</span><span style="" class=""> {</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(41, 161, 152);" class=""><span style="color:rgb(101,123,131)" class="">&nbsp; &nbsp; </span><span style="color:rgb(133,153,1)" class="">return</span><span style="color:rgb(101,123,131)" class=""> </span><span style="" class="">"Unhappy"</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131);" class=""><span style="" class="">}</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131); min-height: 16px;" class=""><span style="" class=""></span><br class=""></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(108, 113, 196);" class=""><span style="" class="">print</span><span style="color:rgb(101,123,131)" class="">(</span><span style="" class="">unhappy</span><span style="color:rgb(101,123,131)" class="">.</span><span style="color:rgb(133,153,1)" class="">dynamicType</span><span style="color:rgb(101,123,131)" class="">)</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(147, 161, 161);" class=""><span style="" class="">//prints:(Int, Int) -&gt; String</span></div></div><div class=""><span style="" class=""><br class=""></span></div><div class="">Haskell Style: Int -&gt; Int -&gt; String</div><div class="">0066 Style: (Int, Int) -&gt; String</div><div class=""><br class=""></div><div class="">Now compare these two functions in their respective styles, which one is clearer to parse at glance?</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(147, 161, 161);" class=""><span style="" class="">// haskell style</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(147, 161, 161);" class=""><span style="" class="">// happy: (Int, Int) -&gt; String</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(147, 161, 161);" class=""><span style="" class="">// unhappy: Int -&gt; Int -&gt; String</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(101, 123, 131); min-height: 16px;" class=""><span style="" class=""></span><br class=""></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(147, 161, 161);" class=""><span style="" class="">// 0066 style</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(147, 161, 161);" class=""><span style="" class="">// happy: ((Int, Int)) -&gt; String</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Monaco; color: rgb(147, 161, 161);" class=""><span style="" class="">// unhappy: (Int, Int) -&gt; String</span></div></div><div class=""><br class=""></div><div class="">Perhaps I am jaded from spending time in a functional programming world (although really not that much), but it is definitely going to take me a while to see that unhappy is accepting 2 separate params, rather than a single tuple params. I think this is more because of how we represent tuple types (like array types) as (Int, Int) or [Int] everywhere else.&nbsp;</div><div class=""><br class=""></div><div class="">In the wild, a tuple type looks like this:</div><div class=""><br class=""></div><div class="">foo: (Int, Int)&nbsp;</div><div class=""><br class=""></div><div class="">but for functions we'll use&nbsp;</div><div class=""><br class=""></div><div class="">fooFunc: ((Int, Int)) -&gt; ()</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<br class="">
&gt; Concern 2:<br class="">
&gt;<br class="">
&gt; There's also the potential to transform a function like this<br class="">
&gt;<br class="">
&gt; A -&gt; B -&gt; C<br class="">
&gt;<br class="">
&gt; into this<br class="">
&gt;<br class="">
&gt; B -&gt; C<br class="">
&gt;<br class="">
&gt; after partial application, something which might not be totally irrelevant to Swift in its future.<br class="">
<br class="">
</span>This isn’t affected by SE-0066 - what is your concern?&nbsp; With SE-0066, the transformation is:<br class="">
<br class="">
(A) -&gt; (B) -&gt; C<br class="">
into:<br class="">
(B) -&gt; C<br class="">
<br class="">
Please keep in mind that SE-0066 doesn’t change the type system, it just adds parens in a very narrow case.<br class=""></blockquote><div class=""><br class=""></div><div class="">I was thinking about partial function application in the context of ordinary functions (i.e. not those that explicitly return functions as well), should that ever be an interesting direction for Swift to head into.&nbsp;</div><div class=""><br class=""></div><div class="">Otherwise, if we look at functions that explicitly return functions, you could still get a nice function type in the Haskell way if you paren the return type:</div><div class=""><br class=""></div><div class="">A -&gt; (B -&gt; C)</div><div class=""><br class=""></div><div class="">which reads more simply to me.</div><div class=""><br class=""></div><div class="">(A) -&gt; (B) -&gt; C isn't as clear to parse in this way, but with practice it doesn't seem like it would be hard to get used to. Perhaps some confusing instances would be:&nbsp;</div><div class=""><br class=""></div><div class="">(A) -&gt; (B) -&gt; (C) where (C) is a single tuple of type C.&nbsp;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">- Mish</div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br class="">
&gt;<br class="">
&gt;<br class="">
&gt; Here are a few contrived examples of function types showing the paren version (order 66), the parens on the return type too, and the generic functional programming version (right). I want to preface this with, "Remember that Swift is an enjoyable experience because reading Swift is pleasant.”<br class="">
<br class="">
0066 does not affect the return type of a function.<br class="">
<span class=""><font color="#888888" class=""><br class="">
-Chris<br class="">
<br class="">
</font></span></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>