<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="">Le 11 déc. 2015 à 20:44, Slava Pestov <<a href="mailto:spestov@apple.com" class="">spestov@apple.com</a>> a écrit :</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=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 11, 2015, at 11:43 AM, Gwendal Roué <<a href="mailto:gwendal.roue@gmail.com" class="">gwendal.roue@gmail.com</a>> 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=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">Le 11 déc. 2015 à 20:34, Slava Pestov via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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="">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 class=""></div><div class="">This would go too far.</div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">Here is an example:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol DatabaseFetchable {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span> mutating func awakeFromFetch()</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>extension DatabaseFetchable {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> func fetch() -> Self {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> var value = /* details omitted */</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> value.awakeFromFetch()</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> return value</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">Gwendal Roué</div><div class=""><br class=""></div></div></div></blockquote></div><br class=""><div class="">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><div class=""><br class=""></div><div class="">Slava</div></div></div></blockquote></div><br class=""><div class="">BTW, we have three workarounds to the initial problem so far, using the current state of Swift:</div><div class=""><br class=""></div><div class="">1. the one by Kevin Ballard below in the thread (the best one)</div><div class="">2. my first work around at <a href="https://bugs.swift.org/browse/SR-142" class="">https://bugs.swift.org/browse/SR-142</a></div><div class="">3. declare a non-mutating protocol that inherits from the mutating one, and let classes adopt the non-mutating one, as in:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol MutableP {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> mutating func f()</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol P : MutableP {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> func f()</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class="">The last workaround is a different in that it leaves room for structs that decide not to mutate in their implementation of the protocol.</div><div class=""><br class=""></div><div class="">You have an example of this approach at <a href="https://github.com/groue/GRDB.swift#databasepersistable-protocol" class="">https://github.com/groue/GRDB.swift#databasepersistable-protocol</a></div><div class=""><br class=""></div><div class="">Gwendal Roué</div><div class=""><br class=""></div></body></html>