<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 26, 2016 at 11:23 AM, Chris Lattner <span dir="ltr">&lt;<a href="mailto:clattner@apple.com" target="_blank">clattner@apple.com</a>&gt;</span> wrote:<br><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="">On Apr 26, 2016, at 10:52 AM, Mishal Awadah via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt; Concern 1:<br>
&gt; I feel like we&#39;re forgetting about the functional programming syntax of declaring function types like this:<br>
&gt;<br>
&gt; A -&gt; B -&gt; C<br>
&gt;<br>
&gt; for a function foo(a: A, b: B) -&gt; C<br>
<br>
</span>This analogy doesn’t exist in Swift, languages like Haskell have auto-currying behavior like this, but Swift does not.<br></blockquote><div><br></div><div>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&#39;s type system, not the existing Swift one, to increase the awareness of the direction this is going. </div><div><br></div><div>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. </div><div><br></div><div>Obviously, if the Haskell-style annotations are a given &quot;we are never going to adopt this in Swift&quot;, then I cannot argue with the increased clarity that 0066 provides, despite the unpleasant parenthesis proliferation it will cause.</div><div> </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>
&gt;<br>
&gt; This eliminates the ambiguity of what the parameter types are, and is more legible (less paren hell) than adding parens like this:<br>
&gt;<br>
&gt; (A,B) -&gt; C<br>
&gt;<br>
&gt; which for a function<br>
&gt;<br>
&gt; foo(a: (A, B)) -&gt; C<br>
&gt;<br>
&gt; would look like this after the implementation of SE-0066:<br>
&gt;<br>
&gt; ((A,B)) -&gt; C<br>
&gt;<br>
&gt; instead of<br>
&gt;<br>
&gt; (A,B) -&gt; C<br>
<br>
</span>I’m not sure what the actual concern you’re pointing out here.  However, you are forgetting the argument labels.  Your foo example will have type:<br>
<br>
(a: (A,B)) -&gt; C<br>
<br>
More to the point thought, this example is *exactly* why SE-0066 is the right thing to do.  You cannot currently write the type of “foo” as &quot;(A,B) -&gt; C”.  (with or without labels), because of the grammar ambiguities that SE-0066 fixes.<br>
<br>
That said, it is likely that I’m totally missing your point here, can you please restate your concern?<br>
<span class=""><br></span></blockquote><div><br></div><div>I&#39;m confused, I created this function and got the type without argument label annotation. </div><div><br></div><div><p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131)"><span style="color:rgb(133,153,1)">func</span><span style=""> happy(a: (</span><span style="color:rgb(181,137,1)">Int</span><span style="">, </span><span style="color:rgb(181,137,1)">Int</span><span style="">)) -&gt; </span><span style="color:rgb(181,137,1)">String</span><span style=""> {</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(41,161,152)"><span style="color:rgb(101,123,131)">    </span><span style="color:rgb(133,153,1)">return</span><span style="color:rgb(101,123,131)"> </span><span style="">&quot;Happy&quot;</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131)"><span style="">}</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131);min-height:16px"><span style=""></span><br></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(133,153,1)"><span style="color:rgb(108,113,196)">print</span><span style="color:rgb(101,123,131)">(</span><span style="color:rgb(108,113,196)">happy</span><span style="color:rgb(101,123,131)">.</span><span style="">dynamicType</span><span style="color:rgb(101,123,131)">)</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131);min-height:16px"><span style="color:rgb(147,161,161)">// prints: (Int, Int) -&gt; String</span><br><span style=""></span></p></div><div> </div><div><br></div><div>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: </div><div><br></div><div>Haskell Style: (Int, Int) -&gt; String</div><div>0066 Style: ((Int, Int)) -&gt; String</div><div><br></div><div>The Haskell Style would remove the ambiguity against a function like this: </div><div><br></div><div><p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131)"><span style="color:rgb(133,153,1)">func</span><span style=""> unhappy(a: </span><span style="color:rgb(181,137,1)">Int</span><span style="">, b: </span><span style="color:rgb(181,137,1)">Int</span><span style="">) -&gt; </span><span style="color:rgb(181,137,1)">String</span><span style=""> {</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(41,161,152)"><span style="color:rgb(101,123,131)">    </span><span style="color:rgb(133,153,1)">return</span><span style="color:rgb(101,123,131)"> </span><span style="">&quot;Unhappy&quot;</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131)"><span style="">}</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131);min-height:16px"><span style=""></span><br></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(108,113,196)"><span style="">print</span><span style="color:rgb(101,123,131)">(</span><span style="">unhappy</span><span style="color:rgb(101,123,131)">.</span><span style="color:rgb(133,153,1)">dynamicType</span><span style="color:rgb(101,123,131)">)</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(147,161,161)"><span style="">//prints:(Int, Int) -&gt; String</span></p></div><div><span style=""><br></span></div><div>Haskell Style: Int -&gt; Int -&gt; String</div><div>0066 Style: (Int, Int) -&gt; String</div><div><br></div><div>Now compare these two functions in their respective styles, which one is clearer to parse at glance?</div><div><br></div><div><p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(147,161,161)"><span style="">// haskell style</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(147,161,161)"><span style="">// happy: (Int, Int) -&gt; String</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(147,161,161)"><span style="">// unhappy: Int -&gt; Int -&gt; String</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(101,123,131);min-height:16px"><span style=""></span><br></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(147,161,161)"><span style="">// 0066 style</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(147,161,161)"><span style="">// happy: ((Int, Int)) -&gt; String</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Monaco;color:rgb(147,161,161)"><span style="">// unhappy: (Int, Int) -&gt; String</span></p></div><div><br></div><div>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. </div><div><br></div><div>In the wild, a tuple type looks like this:</div><div><br></div><div>foo: (Int, Int) </div><div><br></div><div>but for functions we&#39;ll use </div><div><br></div><div>fooFunc: ((Int, Int)) -&gt; ()</div><div><br></div><div><br></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>
&gt; Concern 2:<br>
&gt;<br>
&gt; There&#39;s also the potential to transform a function like this<br>
&gt;<br>
&gt; A -&gt; B -&gt; C<br>
&gt;<br>
&gt; into this<br>
&gt;<br>
&gt; B -&gt; C<br>
&gt;<br>
&gt; after partial application, something which might not be totally irrelevant to Swift in its future.<br>
<br>
</span>This isn’t affected by SE-0066 - what is your concern?  With SE-0066, the transformation is:<br>
<br>
(A) -&gt; (B) -&gt; C<br>
into:<br>
(B) -&gt; C<br>
<br>
Please keep in mind that SE-0066 doesn’t change the type system, it just adds parens in a very narrow case.<br></blockquote><div><br></div><div>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. </div><div><br></div><div>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><br></div><div>A -&gt; (B -&gt; C)</div><div><br></div><div>which reads more simply to me.</div><div><br></div><div>(A) -&gt; (B) -&gt; C isn&#39;t as clear to parse in this way, but with practice it doesn&#39;t seem like it would be hard to get used to. Perhaps some confusing instances would be: </div><div><br></div><div>(A) -&gt; (B) -&gt; (C) where (C) is a single tuple of type C. </div><div><br></div><div><br></div><div>- Mish</div><div> </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>
&gt;<br>
&gt;<br>
&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, &quot;Remember that Swift is an enjoyable experience because reading Swift is pleasant.”<br>
<br>
0066 does not affect the return type of a function.<br>
<span class=""><font color="#888888"><br>
-Chris<br>
<br>
</font></span></blockquote></div><br></div></div>