<div dir="ltr"><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>It seems it would be difficult to write fully generic code with a protocol that has this behavior, because you cannot rely on value semantics at all. To implement ‘mutating’ class methods correctly, you would in fact have to create a new class instance and re-assign to self every time, to preserve old references, since mutating the old value might break users of the protocol that are written as if the witness was a value type. This seems to defeat the whole purpose of using a reference type in fact.</div></blockquote><div><br></div><div>Agreed. That description even seems to sound like a rehashing of the same problem, but from a more strictly value-centric approach.</div><div><br></div><div>The &#39;one-element struct&#39; solution isn&#39;t what I was looking for, here. I wasn&#39;t trying to achieve copy-on-write of a whole object structure, but instead writing more fully generic code. Also, not having to use an awkward workaround (i.e. the var this = self; this.mutatingMethod()).</div><div><br></div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>I guess the question is, does it even make sense to write a protocol that can be adopted by both a struct and a class, if the protocol has mutating members?</div></blockquote><div><br></div><div>I think so. But I think part of the problem is that protocol members are currently interpreted in terms of value semantics, but protocols are, of course, widely used in reference semantics, too.</div><div><br></div><div>To me, it feels like we&#39;re lacking a degree of fidelity. That&#39;s why my initial proposition was a `mutating`-ish operator that applies specifically to this scenario, and provides a more nuanced bridging to reference semantics (feels vaguely similar in nature to unowned vs. weak modifiers).</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 11, 2015 at 11:44 AM, Slava Pestov <span dir="ltr">&lt;<a href="mailto:spestov@apple.com" target="_blank">spestov@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class="h5"><br><div><blockquote type="cite"><div>On Dec 11, 2015, at 11:43 AM, Gwendal Roué &lt;<a href="mailto:gwendal.roue@gmail.com" target="_blank">gwendal.roue@gmail.com</a>&gt; wrote:</div><br><div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>Le 11 déc. 2015 à 20:34, Slava Pestov via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; a écrit :</div><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">For this reason I’m in favor of going in the opposite direction, and prohibiting classes from conforming to protocols with mutating requirements.</div></div></blockquote><br></div><div>This would go too far.</div><div><br></div><div>It’s common to write a protocol with mutating methods just because the protocol designer expects that some adopting structs may want to mutate in their implementation. And in this case the goal of the protocol designer is certainly not to limit the protocol adoption to structs.</div><div><br></div><div>Here is an example:</div><div><br></div><div><span style="white-space:pre-wrap">        </span>protocol DatabaseFetchable {</div><div><span style="white-space:pre-wrap">        </span>  mutating func awakeFromFetch()</div><div><span style="white-space:pre-wrap">        </span>}</div><div><span style="white-space:pre-wrap">        </span>extension DatabaseFetchable {</div><div><span style="white-space:pre-wrap">        </span>  func fetch() -&gt; Self {</div><div><span style="white-space:pre-wrap">        </span>    var value = /* details omitted */</div><div><span style="white-space:pre-wrap">        </span>    value.awakeFromFetch()</div><div><span style="white-space:pre-wrap">        </span>    return value</div><div><span style="white-space:pre-wrap">        </span>  }</div><div><span style="white-space:pre-wrap">        </span>}</div><div><br></div><div>The protocol does not care at all if awakeFromFetch mutates or not. But the protocol designer does: if the awakeFromFetch method were not declared mutating, many structs could simply not adopt it.</div><div><br></div><div>Gwendal Roué</div><div><br></div></div></div></blockquote></div><br></div></div><div>I guess the question is, does it even make sense to write a protocol that can be adopted by both a struct and a class, if the protocol has mutating members?</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Slava</div></font></span></div></blockquote></div><br></div>