<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 29 Jul 2016, at 18:42, Bram Beernink via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</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="">Hi all,<div class=""><br class=""></div><div class="">Would it be possible to improve value and move semantics (performance) in Swift? Consider this possible Swift code in a future release of Swift:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> array1 : [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span>] = [<span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"Val1"</span>, <span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"Val2"</span>]</div><div style="margin: 0px;" class=""><span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">let</span><span style="font-family: Menlo; font-size: 11px;" class=""> array2 = </span><span style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;" class="">array1</span><span style="font-family: Menlo; font-size: 11px;" class="">.appended(</span><font color="#d12f1b" face="Menlo" class=""><span style="font-size: 11px;" class="">“Val3”</span></font><font face="Menlo" class=""><span style="font-size: 11px;" class="">) </span></font><font color="#008400" face="Menlo" class=""><span style="font-size: 11px;" class="">// Copy of array1 with&nbsp;“Val3”&nbsp;appended. array1 is left untouched. Nothing special yet.</span></font></div><div style="margin: 0px;" class=""><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">var</span><font face="Menlo" class=""><span style="font-size: 11px;" class=""> array3</span></font><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;: [</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">String</span><span style="font-family: Menlo; font-size: 11px;" class="">]&nbsp;</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">= [</span></font><font color="#d12f1b" face="Menlo" class=""><span style="font-size: 11px;" class="">“Var1</span></font><font face="Menlo" class=""><font color="#d12f1b" class=""><span style="font-size: 11px;" class="">”</span></font><span style="font-size: 11px;" class="">]</span></font></div><div style="margin: 0px;" class=""><span style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;" class="">array3</span><span style="font-family: Menlo; font-size: 11px;" class=""> = </span><span style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;" class="">array3</span><span style="font-family: Menlo; font-size: 11px;" class="">.appended(</span><font color="#d12f1b" face="Menlo" class=""><span style="font-size: 11px;" class="">“Var2”</span></font><font face="Menlo" class=""><span style="font-size: 11px;" class="">) </span></font><font color="#008400" face="Menlo" class=""><span style="font-size: 11px;" class="">// <b class="">array3 can just be mutated to add&nbsp;“Var2”</b>, while maintaining value semantics. Swift can recognize that array3’s old state is not referenced anywhere in the future.</span></font></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> array4 = array2.appended(</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"Val4"</span><span style="font-variant-ligatures: no-common-ligatures;" class="">).appended(</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">"Val5"</span><span style="font-variant-ligatures: no-common-ligatures;" class="">) </span>// Copy of array2 with both "Val4" and "Val5" appended. In this case, “Val5” can also be appended by mutation.</div></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0);" class=""><br class=""></div><div style="margin: 0px;" class=""><div style="font-family: Helvetica; font-size: 12px;" class="">This example illustrates improved value semantics with a string array. But it would be good if this can work with any struct. Maybe via something similar to&nbsp;<span style="color: rgb(61, 29, 129); font-family: Menlo; font-size: 11px;" class="">isUniquelyReferenced?&nbsp;</span>Or maybe you can even have a “smart” self in a non-mutating func in a struct:</div><div class=""><div style="margin: 0px;" class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> Array&lt;T&gt; {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">func</span> appended(e : <span style="color: rgb(112, 61, 170);" class="">T</span>) -&gt; <span style="color: rgb(79, 129, 135);" class="">Array</span>&lt;<span style="color: rgb(112, 61, 170);" class="">T</span>&gt; { <span style="color: rgb(0, 132, 0);" class="">// No mutating keyword!</span></div><div style="margin: 0px;" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></font><span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">self</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">.append(e) </span></font><font color="#008400" face="Menlo" class=""><span style="font-size: 11px;" class="">// <b class="">self would either be mutated here if the current ref count of self is 1, and self is either a “rvalue” or self’s old state cannot possibly referenced anymore after this call. Otherwise, "self” would actually be a copy of self.</b></span></font></div><div style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px; margin: 0px;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span>return<span style="font-variant-ligatures: no-common-ligatures;" class=""> </span>self</div><div style="font-family: Menlo; font-size: 11px; margin: 0px;" class="">&nbsp; &nbsp; }</div><div style="font-family: Menlo; font-size: 11px; margin: 0px;" class="">}</div></div></div><div style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></div><div style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">I think that with such support it is encouraged to make more use of (immutable) value types while not sacrificing performance. Less mutations lead to more understandable code, which leads to less bugs.</span></div><div style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">In any case, keep up the fast improvements to Swift.</span></div><div style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Best regards,</span></div><div style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Bram.</span></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""><div class="">It’s a known issue. See:&nbsp;<a href="https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#advice-use-inplace-mutation-instead-of-object-reassignment" class="">https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#advice-use-inplace-mutation-instead-of-object-reassignment</a></div><div class=""><br class=""></div><div class="">I’m not a compiler expert, but in theory I’d expect a smart-enough, fast-enough optimiser to be able to replace those with mutating calls.&nbsp;</div><div class=""><br class=""></div><div class="">Karl</div></body></html>