<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 28, 2016, at 12:34 AM, Pyry Jahkola &lt;<a href="mailto:pyry.jahkola@iki.fi" class="">pyry.jahkola@iki.fi</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Good that you brought the topic of "fluent" interfaces up. I don't see any problem with explicit value type mutation and method chaining because fluent interfaces are constrained to reference types by the language. Details below:</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 28 Apr 2016, at 03:44, Tyler Cloutier &lt;<a href="mailto:cloutiertyler@aol.com" class="">cloutiertyler@aol.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">How would this chain if I wanted to do something like:</div><div style="font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-variant-caps: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" style="font-size: 11px;" class="">let median = foo.calculateBigHugeArray().sort().medianValue()</font></div><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);">and I want the sort to be done in place.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I think I can guess what you wanted the above to mean but, mind you, the in-place sort returns `<font face="Menlo" class=""><span style="font-size: 11px;" class="">()</span></font>` so you wouldn't chain its result like that. On the other hand, the above code already works using the non-mutating `<font face="Menlo" class=""><span style="font-size: 11px;" class="">.sort()</span></font>` (to be known as `<font face="Menlo" class=""><span style="font-size: 11px;" class="">.sorted()</span></font>` in Swift 3), and—correct me if I'm wrong—the compiler probably optimises the copy away using copy-on-write anyway.</div><br class=""><blockquote type="cite" class=""><div style="font-variant-caps: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);">Or will this type of thing just be disallowed in favor of.</div><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" style="font-size: 11px;" class="">let array = foo.calculateBigHugeArray()</font></div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" style="font-size: 11px;" class="">mutate array.sort()</font></div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" style="font-size: 11px;" class="">let median = array.medianValue()&nbsp;</font></div></div></blockquote><div class=""><br class=""></div><div class="">Yes, I think mutating code should be written in many statements rather than squeezing everything into one long expression.</div><div class=""><br class=""></div><div class="">Indeed, <b class="">no currently working method chaining would be disallowed </b>in my proposal<b class="">.</b>&nbsp;Let's consider the example of "fluent API" for value types, i.e. one where you'd extensively `<font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">return self</b></span></font>` in `<font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">mutating</b></span></font>` methods. Firstly, the stdlib doesn't practice that at all. And I failed to find any popular Swift libraries that would do so on Github either. The reason is simple: fluent mutating APIs on value types don't work.</div><div class=""><br class=""></div><div class="">Consider the following silly example that shortens an array in half (but demonstrates the use of `<font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">return self</b></span></font>` in a `<font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">mutating</b></span></font>` method):</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">extension</b> Array {</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <b class="">mutating</b> <b class="">func</b> halve() -&gt; Array {</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b class="">self</b> = <b class="">self</b>[0 ..&lt; count / 2]</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b class="">return</b> <b class="">self</b></span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</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="">Suppose I want to get the result of halving an array twice. What happens?</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; <b class="">var</b> xs = [1,2,3,4,5,6,7,8]</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; xs.halve().halve()</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; </span><font color="#919191" style="font-size: 11px;" class="">//&nbsp;<b class="">error:</b> cannot use mutating member on immutable value: function call returns immutable value</font></font></div><div class=""><br class=""></div><div class="">So no, fluent APIs on value types are not a thing in Swift. Not now at least. Making mutation explicit along this proposal has nothing to do with fluent APIs.</div><br class=""><blockquote type="cite" class=""><div style="font-variant-caps: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);">Alternately you could replace the method invocation operator with &amp;</div><div class="" style="margin: 0px; line-height: normal;"><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; color: rgb(69, 69, 69); margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" style="font-size: 11px;" class="">let median = foo.calculateBigHugeArray()&amp;sort().medianValue()</font></div></div></div></blockquote><div class=""><br class=""></div><div class="">Don't you think that's too prone to getting mixed up with the binary `<font face="Menlo" class=""><span style="font-size: 11px;" class="">&amp;</span></font>` operator?</div><div class=""><br class=""></div><blockquote type="cite" class=""><div style="font-variant-caps: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);">Also, if you wanted to stick with consistent &amp; syntax, you could do:</div><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" style="font-size: 11px;" class="">&amp;c.frobnicate(i)</font></div><div class="" style="font-family: Helvetica; font-size: 13px; font-weight: normal; font-style: normal; margin: 0px; line-height: normal; color: rgb(69, 69, 69);">and&nbsp;</div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" style="font-size: 11px;" class="">let k = &amp;c.frobnicate(&amp;i)</font></div></div></blockquote></div><div class=""><br class=""></div><div class="">Yeah, probably. However, one place where that notation falls short compared to a prefixing keyword like `<font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">mutate</b></span></font>` is when mutating `<font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">self</b></span></font>`:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""><b class="">&nbsp; &nbsp; extension</b> Array {</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// Apologies for not having the time to think of a less contrived example than this!</font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<b class="">mutating</b> <b class="">func</b> quarter() {</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><b style="font-size: 11px;" class="">mutate</b> <b style="font-size: 11px;" class="">self</b><span style="font-size: 11px;" class="">.halve() </span><font color="#919191" style="font-size: 11px;" class="">// Ever since</font><font color="#919191" style="font-size: 11px;" class="">&nbsp;</font><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0009-require-self-for-accessing-instance-members.md" style="font-size: 11px;" class="">SE-0009</a><font color="#919191" style="font-size: 11px;" class="">, </font><font color="#919191" style="font-size: 11px;" class="">it's unusual to use `self` here.</font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><b style="font-size: 11px;" class="">mutate</b><span style="font-size: 11px;" class=""> halve() &nbsp; &nbsp; &nbsp;</span><font color="#919191" style="font-size: 11px;" class="">// Where would you put the `&amp;` prefix in this?</font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; }</span></font></div><br class=""><div class="">— Pyry</div><div class=""><br class=""></div></div></div></blockquote></div><br class=""><div class="">You are very correct. Yup, that pretty much addresses all of my concerns. So count me amongst the fans.&nbsp;</div><div class=""><br class=""></div><div class="">I had something like popLast in mind, but as you point out, return values are immutable in Swift.</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Foo {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> y = [</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">5</span><span style="font-variant-ligatures: no-common-ligatures" class="">, </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">6</span><span style="font-variant-ligatures: no-common-ligatures" class="">]</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> foo() -&gt; [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">] {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">y</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> x = </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Foo</span><span style="font-variant-ligatures: no-common-ligatures" class="">()</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">x</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">foo</span><span style="font-variant-ligatures: no-common-ligatures" class="">().popLast()?.advanced(by: </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span><span style="font-variant-ligatures: no-common-ligatures" class="">) // error: Cannot use mutating member on immutable value: function call returns immutable value</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Thanks!&nbsp;</span></span></div></div></div></body></html>