<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=""><div class=""></div><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""></div></div></div></div><blockquote type="cite" class=""><div class="">On 29 Jul 2016, at 17:42, Bram Beernink via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">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 class="" style="margin: 0px; font-size: 11px; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">let</span>&nbsp;array1 : [<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">String</span>] = [<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">"Val1"</span>,&nbsp;<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">"Val2"</span>]</div><div class="" style="margin: 0px;"><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">let</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;array2 =&nbsp;</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;">array1</span><span class="" style="font-family: Menlo; font-size: 11px;">.appended(</span><font color="#d12f1b" face="Menlo" class=""><span class="" style="font-size: 11px;">“Val3”</span></font><font face="Menlo" class=""><span class="" style="font-size: 11px;">)&nbsp;</span></font><font color="#008400" face="Menlo" class=""><span class="" style="font-size: 11px;">// Copy of array1 with&nbsp;“Val3”&nbsp;appended. array1 is left untouched. Nothing special yet.</span></font></div><div class="" style="margin: 0px;"><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">var</span><font face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp;array3</span></font><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;: [</span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">String</span><span class="" style="font-family: Menlo; font-size: 11px;">]&nbsp;</span><font face="Menlo" class=""><span class="" style="font-size: 11px;">= [</span></font><font color="#d12f1b" face="Menlo" class=""><span class="" style="font-size: 11px;">“Var1</span></font><font face="Menlo" class=""><font color="#d12f1b" class=""><span class="" style="font-size: 11px;">”</span></font><span class="" style="font-size: 11px;">]</span></font></div><div class="" style="margin: 0px;"><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;">array3</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;=&nbsp;</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;">array3</span><span class="" style="font-family: Menlo; font-size: 11px;">.appended(</span><font color="#d12f1b" face="Menlo" class=""><span class="" style="font-size: 11px;">“Var2”</span></font><font face="Menlo" class=""><span class="" style="font-size: 11px;">)&nbsp;</span></font><font color="#008400" face="Menlo" class=""><span class="" style="font-size: 11px;">//&nbsp;<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 class="" style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0);"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">let</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;array4 = array2.appended(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">"Val4"</span><span class="" style="font-variant-ligatures: no-common-ligatures;">).appended(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">"Val5"</span><span class="" style="font-variant-ligatures: no-common-ligatures;">)&nbsp;</span>// Copy of array2 with both "Val4" and "Val5" appended. In this case, “Val5” can also be appended by mutation.</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Well, for the array3 = array3.appended("Var2") example this could possibly be addressed by an attribute to indicate to the compiler that .appended() has a mutating variant, as this will allow it to issue a warning when the assignment is to the same variable, which would address that simple case (and provide more awareness of the mutating options and encourage developers to use them).</div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span 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><span class="" style="color: rgb(61, 29, 129);">isUniquelyReferenced?&nbsp;</span><span style="font-family: Helvetica; font-size: 12px;" class="">Or maybe you can even have a “smart” self in a non-mutating func in a struct:</span></div><div style="margin: 0px;" class=""><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></div></blockquote></div><br class=""><div class="">I don't know about allowing mutation of self in non-mutating methods, that seems confusing; however, I'd be surprised if the compiler doesn't already detect variables that only exist to create a copy that is discarded.</div><div class=""><br class=""></div><div class="">The compiler should already be trying to inline very simple methods like the common copy -&gt; mutate -&gt; return style of non-mutating implementations, in which case it should be able to identify that a copy is being created only to overwrite the original anyway, so can be eliminated. Do you believe that this isn't currently being done?</div></body></html>