<div dir="ltr">On Wed, Jun 7, 2017 at 19:15 Víctor Pimentel Rodríguez &lt;<a href="mailto:vpimentel@tuenti.com" target="_blank">vpimentel@tuenti.com</a>&gt; wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div><div id="m_-904681581836203480m_-1631415452655102727gmail-m_5390901663128795696gmail-m_329855592564616797gmail-m_9192218381219942629m_8434010345691910164AppleMailSignature">On 7 Jun 2017, at 21:29, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:<br></div></div><blockquote type="cite"><div><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div>SE-0110 may be an obvious extension of the proposed goal, but it is clear that it has been implemented in Swift 4, and that the consequences are derived of those changesets.</div><div><br></div><div>Those &quot;unwanted&quot; consequences can be reverted by temporarily reverting SE-0110, without touching any other previous proposal.</div><div><br></div><div>In no place I see Gwendal asking for full reversal of 5 proposals. He is just voicing something that a lot of app developers and library maintainers are not going to understand in September.</div><div><br></div><div>For example, you can see all the changes needed in RXSwift so that it compiles to Swift 4:</div><div><br></div><div><a href="https://github.com/ReactiveX/RxSwift/pull/1282/commits/915e00fa6d1e59d58cd8c38dd6dc83765fc67fe4" target="_blank">https://github.com/ReactiveX/<wbr>RxSwift/pull/1282/commits/<wbr>915e00fa6d1e59d58cd8c38dd6dc83<wbr>765fc67fe4</a><br></div><div><br></div>I would not want to migrate to Swift 4 an app using such framework.</div></div><div><div><br><blockquote type="cite"><div><div><div class="gmail_quote"><div>I asked you in my first reply to you, is your view that the distinction itself between (Int, Int) -&gt; Int and ((Int, Int)) -&gt; Int is problematic? If so, this is a very different discussion from seeking solutions to mitigate particular ergonomic issues that arise from the change. However, you have not answered the question.</div></div></div>
</div></blockquote><div><br></div></div></div><div><div><div>As far as I can see, the bigger usability regressions are caused when using generics, specially in collections and functional utilities. When you specify that type with a tuple, as in Dictionary, then all the related methods start receiving closures receiving tuples.</div><div><br></div><div>Notice that allowing some syntactic sugar on the call site of those closures may not be enough, since you may have stored or passed a closure for customization purposes.</div></div></div></blockquote><div><br></div><div>Can you illustrate this with an example? I’m not sure I understand what you’re getting at here.</div></div></div></blockquote><div><br></div></div></div><div><div><div>Sure. Let&#39;s say you want to filter some elements from a dictionary, and you have this valid Swift 3 code:</div><div><br></div><div>let conversationsById: [String: Conversation]</div><div>let unreadConversations = conversationsById.filter { $1.isUnread }</div><div><br></div><div>Or:</div><div><br></div><div><span style="background-color:rgba(255,255,255,0)">let unreadConversations = conversationsById.filter { id, c in</span></div><div><span style="background-color:rgba(255,255,255,0)">    return !id.isEmpty &amp;&amp; c.isUnread</span></div><div><span style="background-color:rgba(255,255,255,0)">}</span></div><div><br></div><div>Neither of these expressions are permitted in Swift 4, but some syntactic sugar can be added to allowing it again without the need of full tuple splatting.</div></div></div></blockquote><div><br></div><div>Right.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div>However, if for some reason you want to pass around a filter closure, you will still have mismatch types:</div><div><br></div><div><div>func first(passing filter: (String, Conversation) -&gt; Bool) -&gt; Conversation? {</div><div>    return conversationsById.filter(<wbr>filter).first?.value</div><div>}</div></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div><div><br></div></div><div>This example is simple and useless and contrived, but it gets even worse when you take generics into account to catch any type of closure.</div></div></div></blockquote><div><br></div><div>I’m not going to raise any issues over how realistic the scenario might be. It&#39;s for answering a question, after all.</div><div><br></div><div>However, what I don’t get is why you’d have a mismatch here. Your method `first` accepts a closure, and surely the type it expects should be `((String, Conversation)) -&gt; Bool` instead, since that is the type that the `filter` method expects in the body of your implementation?</div><div><br></div><div>Certainly, there are scenarios not possible (or at least, very difficult) without tuple splatting, but that’s straight-up an argument for tuple splatting. That&#39;s, IMO, an unnecessary argument, since the usefulness of the feature has never been in question, only the resources to design and implement.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><blockquote type="cite"><div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div><div>This behavior is so hurtful to functional style programming, that I think either SE-0110 should be reverted, or alternatives like this Susan proposal should be implemented.</div></div></div></div></blockquote><div><br></div><div>To be clear, what you and Gwendal are objecting to is the loss of tuple splatting, is it not? Again, SE-0110 is only the final piece; SE-0029 is what removed implicit tuple splatting. As that proposal said, a properly designed explicit tuple splatting can be considered if there’s demand, and it was understood that removing this functionality would be a regression and nonetheless the decision for removal was still deliberately undertaken. Re-reading that proposal, the rationale was that it never worked correctly to begin with, and the barrier for bringing it back is that it requires considerable effort to design and implement the feature correctly.</div></div></div></blockquote></div></div><div><div><div><div>I&#39;m sorry if there has been any disrespect for my part, I appreciate what you all do here. But sometimes it&#39;s a bit frustrating having to explain why something that seems obvious to us is not obvious to others.</div><div><br></div><div>I think that you have a bigger picture from the Swift Evolution point, but the thing is that Swift users like me doesn&#39;t have that context, and we are baffled when we encounter that some pretty simple code turns into a weird thing in a migration. I have linked to several real examples out there, and it seems to be a popular opinion. Nevertheless, it was Tony Parker&#39;s mail the one that kindled this discussion with a really simple question.</div></div><div><br></div><div>It may be the last piece, but it is the piece that impacted simple code the most, or at least the one that had the most unexpected consequences. Certainly that proposal does not contain nearly enough code examples or goes deeply enough. And this is subjective, but for me this isn&#39;t true: &quot;Minor changes to user code may be required if this proposal is accepted.&quot;</div></div></div></blockquote><div><br></div><div>SE-0110 is short not because there wasn’t thought devoted to the change but because that thought was largely already undertaken elsewhere (for example, in SE-0029). As far as I can tell, the only part of SE-0110 that actually required review as a proposal was the double-parenthesis syntax for a single argument of tuple type; beyond that, I cannot understand how SE-0029 could be considered implemented without implementing SE-0110.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div></div><div>The fact that it affects even the standard library shows how hurtful removing this feature is. It&#39;s not a nice-to-have feature or a somewhat-useful feature, it&#39;s that right now it&#39;s very difficult to model something as essential as Dictionary with a nice-to-use API. So lots of other custom types will suffer too.</div></div></div></blockquote><div><br></div><div>I think “very difficult” is a stretch; suffice it to say that it’s a step back in ergonomics that may disproportionately affect certain programming styles.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div></div><div>If we all agree that this is a loss of ergonomics, then the Core Team have several options for Swift 4:</div><div><br></div><div>1. Do nothing.</div><div>2. Revert SE-0110 related changes.</div><div>3. Add a complex tuple-splatting feature.</div><div>4. Add some syntactic sugar keeping the same syntax.</div><div>5. Add some syntactic sugar but changing the syntax.</div><div><br></div><div>For me:</div><div><br></div><div>1. I want to avoid this, and I think Gwendal and others too.</div><div><div>2. I know nothing about how it was implemented, but for the time being it would be the best option for me, as it would avoid painful migrations where you are forced to make your code worse. But if it&#39;s too difficult to do, I understand.<br></div><div>3. No time for this.</div><div>4. Probably no time for this, and I don&#39;t think it would not cover all the regressions (like the example of passing a closure).</div></div></div></div></blockquote><div><br></div><div>My point is that some (many?) of the regressions are intentional (i.e. loss of implicit tuple splatting generally); Gwendal and others may not like it, but that&#39;s not grounds for disputing an approved proposal. The aim of the conversation should be focusing on the regressions that are _unintentional_, since unintentional consequences do represent grounds for revisiting a proposal. Pervasively littering `$0.0` inside closures was not foreseen (or at least discussed, as far as I recall), and that can be mitigated by allowing tuple destructuring in the closure parameter shorthand, whether with new syntax or not. A complete implementation of this feature has never actually existed in Swift, but it would certainly be useful.</div><div><br></div><div>There is no need to speculate as to whether it would be replaced in future version of Swift; if it is useful enough to be included now, it should be included for all time; otherwise, it should not be included at all.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div><div>5. It will also hurts a bit the ergonomics, but more importantly it will hurt the migrations. And this will probably be replaced in next versions of Swift, so it&#39;s very suboptimal, I think.</div></div><div><br></div><div>Anyway, I may disagree with the result, but if it&#39;s what the Core Team wants or needs then ¯\_(ツ)_/¯</div><div><br></div><div>--</div><div>Víctor Pimentel</div></div></div>
</blockquote></div></div>