<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br></div><div>Le 28 avr. 2016 à 03:34, Pyry Jahkola via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> a écrit :<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><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><blockquote type="cite" class=""><div class="">On 28 Apr 2016, at 03:44, Tyler Cloutier <<a href="mailto:cloutiertyler@aol.com" class="">cloutiertyler@aol.com</a>> 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 color="#000000" 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><br class=""></div><div>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 color="#000000" face="Menlo" style="font-size: 11px;" class="">let array = foo.calculateBigHugeArray()</font></div><div class="" style="margin: 0px; line-height: normal;"><font color="#000000" face="Menlo" style="font-size: 11px;" class="">mutate array.sort()</font></div><div class="" style="margin: 0px; line-height: normal;"><font color="#000000" face="Menlo" style="font-size: 11px;" class="">let median = array.medianValue() </font></div></div></blockquote><div><br class=""></div><div>Yes, I think mutating code should be written in many statements rather than squeezing everything into one long expression.</div><div><br class=""></div><div>Indeed, <b class="">no currently working method chaining would be disallowed </b>in my proposal<b class="">.</b> 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><br class=""></div><div>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><br class=""></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> <b class="">extension</b> Array {</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> <b class="">mutating</b> <b class="">func</b> halve() -> Array {</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> <b class="">self</b> = <b class="">self</b>[0 ..< count / 2]</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> <b class="">return</b> <b class="">self</b></span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> }</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> }</span></font></div><div><br class=""></div><div>Suppose I want to get the result of halving an array twice. What happens?</div><div><br class=""></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> <b class="">var</b> xs = [1,2,3,4,5,6,7,8]</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> xs.halve().halve()</span></font></div><div><font face="Menlo" class=""><span style="font-size: 11px;" class=""> </span><font color="#919191" style="font-size: 11px;" class="">// <b class="">error:</b> cannot use mutating member on immutable value: function call returns immutable value</font></font></div><div><br class=""></div><div>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></div></div></blockquote><div><br></div>But is this limitation as per design, or just something that no one reported as a bug yet? When acting on large piece of data and simple operations one might want to chain mutable version (to avoid large allocation) of the operations as a single stream (à la functional programming) instead of having to use multiple line of:<div> mutate largeData.operation()</div><div><br></div><div>On a side note, this "long" explicit 'mutate' keyword could be seen by some as a way to impose the use immutability by making it harder (more to type) to use mutability.</div><div><br></div><div>Also, this 'mutate' could maybe help to differentiate between sort() 2.2-style and sort() 3.0-style, and avoid endless discussion on InPlace/form/ed/ing. But for language uniformity, would this new 'mutate' keyword be required on nearly every single standard OOP methods?</div><div><br></div><div>mutate graph.pencil.changeColor(Red) // the color properties of pencil is mutated</div><div>mutate graph.pencil.changeWidth(wide)</div><div>mutate graph.drawFrame() // the graphic is altered/mutated</div><div><br></div><div>Not proposing, just asking.</div><div><br></div><div>Dany</div><div><div><br><div><blockquote type="cite"><div><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 &</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 color="#000000" face="Menlo" style="font-size: 11px;" class="">let median = foo.calculateBigHugeArray()&sort().medianValue()</font></div></div></div></blockquote><div><br class=""></div><div>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="">&</span></font>` operator?</div><div><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 & 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 color="#000000" face="Menlo" style="font-size: 11px;" class="">&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 </div><div class="" style="margin: 0px; line-height: normal;"><font color="#000000" face="Menlo" style="font-size: 11px;" class="">let k = &c.frobnicate(&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=""> extension</b> Array {</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> </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=""> <b class="">mutating</b> <b class="">func</b> quarter() {</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> </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=""> </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=""> </span><b style="font-size: 11px;" class="">mutate</b><span style="font-size: 11px;" class=""> halve() </span><font color="#919191" style="font-size: 11px;" class="">// Where would you put the `&` prefix in this?</font></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> }</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> }</span></font></div><br class=""><div class="">— Pyry</div><div class=""><br class=""></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></div></div></body></html>