<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 11 Oct 2016, at 12:59, Jay Abbott &lt;<a href="mailto:jay@abbott.me.uk" class="">jay@abbott.me.uk</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class="">This is interesting. I'm trying to evaluate your statement that "No setter would be needed if a mutation clause is provided" but I can't think exactly what the compiler would do in the case where there is a 'get' and 'mutate', but no 'set'...<br class="">a) when you call a non-mutating function;<br class=""></div></div></div></div></div></blockquote><div><br class=""></div><div>This would just call the getter and call the function on the result, exactly how it works right now.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">b) when you assign a new value.<br class=""></div></div></div></div></blockquote><div><br class=""></div><div>A setter would be a special case of a “mutator”, where the starting value of the inout parameter is ignored. So the mutate clause would be invoked with `{ (x: inout T) in x = newValue }`. Does that make sense?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">c) when get and set aren't implemented with a matching hidden var (i.e. using a bit in an int var or storing in a dictionary).<br class=""></div></div></blockquote><div><br class=""></div><div>I’m not sure what you mean by this. The getter and setter are implemented, but the mutator isn’t? Could you clarify?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class=""></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Tue, 11 Oct 2016 at 11:26 Tim Vermeulen via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">Just having getters and setters doesn’t allow this (unless the optimiser is really smart about it). All the current API allows is grabbing whatever the `get` clause returns, mutating it, and then passing it into the `set` clause, whatever that does. The `set` clause might not do anything, or what it does could be seemingly unrelated to the `get` clause, so it’s not a trivial task to optimise this.</div><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On 11 Oct 2016, at 06:35, Erica Sadun &lt;<a href="mailto:erica@ericasadun.com" class="gmail_msg" target="_blank">erica@ericasadun.com</a>&gt; wrote:</div><br class="gmail_msg m_-3171040892318422003Apple-interchange-newline"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Oct 10, 2016, at 9:53 PM, Tim Vermeulen via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="gmail_msg m_-3171040892318422003Apple-interchange-newline"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg">There have been many instances where unexpected bad performance was caused by the interplay between getters, setters, mutations and the copy-on-write mechanism. For example:<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">struct</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> Foo {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">private</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">var</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> _array: [</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">] = [</span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">1</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">2</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">3</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">4</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">5</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">]</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp;&nbsp; &nbsp;</span><br class="gmail_msg m_-3171040892318422003webkit-block-placeholder"></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">var</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> array: [</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">] {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">get</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> { </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">return</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">_array</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">set</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> { </span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">_array</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> = newValue }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"></span><br class="gmail_msg"></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">var</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> foo = </span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Foo</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">()</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">foo</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">array</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#3e1e81" class="gmail_msg">append</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8" class="gmail_msg">6</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">) </span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">// an O(n) operation</span></div></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I propose a `mutate` clause which provides a `mutate` function with a single inout parameter (similar to how `set` provides `newValue`), which can be used instead of a setter:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">var</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> array: [</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">] {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp;&nbsp;</span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">get</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> { </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">return</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">_array</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp;&nbsp;<span style="color:rgb(186,45,162)" class="gmail_msg">mutate</span>&nbsp;{&nbsp;<span style="color:rgb(49,89,93)" class="gmail_msg">mutate</span>(&amp;<span style="color:rgb(79,129,135)" class="gmail_msg">_array</span>) }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">The compiler could then translate each mutation of `foo.array` to a closure with an inout parameter, which is then passed into the `mutate` clause (which in turn is executed with `_array` as its argument, as per the snippet above). For example, for `foo.array.append(6)`, the compiler would internally generate the closure `{ (arr: inout [Int]) in arr.append(6) }` and pass it into the `mutate` clause, `_array` is then passed as its parameter and the array is updated in constant time.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I apologise if that was too hard to follow.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">No setter would be needed if a mutation clause is provided, but I see no good reason to do away with setters altogether, so this proposal would be purely additive.</div></div></div></blockquote><br class="gmail_msg"></div><div class="gmail_msg">If this is computationally better, why is it not the default behavior rather than an API change?</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">-- E</div><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"></div></div></blockquote></div><br class="gmail_msg"></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>
</div></blockquote></div><br class=""></body></html>