<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Hooman,<div class=""><br class=""></div><div class="">Since the protocol P is not class-bounded, the requirement can be witnessed by a protocol extension method which re-assigns ‘self’:</div><div class=""><br class=""></div><div class="">protocol Initable {</div><div class=""> init()</div><div class="">}</div><div class=""><br class=""></div><div class="">extension P where Self : Initable {</div><div class=""> mutating func f(_ x: Int) -> Int {</div><div class=""> self = Self()</div><div class=""> return x</div><div class=""> }</div><div class="">}</div><div class=""><br class=""></div><div class="">class C : P, Initable {</div><div class=""> required init() {}</div><div class="">}</div><div class=""><br class=""></div><div class="">Now imagine you could do this,</div><div class=""><br class=""></div><div class="">let x: P & AnyObject</div><div class=""><br class=""></div><div class="">x.f(12)</div><div class=""><br class=""></div><div class="">This would be invalid because ‘x’ is a let binding but the requirement ‘f’ is witnessed by the protocol extension method, which performs a mutating access of ‘self’.</div><div class=""><br class=""></div><div class="">Slava</div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Dec 21, 2017, at 6:01 PM, Hooman Mehr via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</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; line-break: after-white-space;" class=""><div class="">The title is confusing, let me clarify by example:</div><div class=""><br class=""></div><div class="">We have this protocol with a mutating method:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class="">protocol<span style="" class=""> P { </span>mutating<span style="" class=""> </span>func<span style="" class=""> f(</span>_<span style="" class=""> x: </span><span style="color: #703daa" class="">Int</span><span style="" class="">) -> </span><span style="color: #703daa" class="">Int</span><span style="" class=""> }</span></div></div><div class=""><br class=""></div><div class="">And a conforming class (which has to conform with a non-mutating method):</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">class</span> C: <span style="color: #4f8187" class="">P</span> { <span style="color: #ba2da2" class="">func</span> f(<span style="color: #ba2da2" class="">_</span> x: <span style="color: #703daa" class="">Int</span>) -> <span style="color: #703daa" class="">Int</span> { <span style="color: #ba2da2" class="">return</span> x } }</div></div><div class=""><br class=""></div><div class="">An instance of this class can be used with a let constant:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span> c = <span style="color: #4f8187" class="">C</span>()</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #4f8187" class="">c</span><span style="" class="">.</span><span style="color: #31595d" class="">f</span><span style="" class="">(</span><span style="color: #272ad8" class="">1</span><span style="" class="">) </span>// OK</div></div><div class=""> </div><div class="">If we make it an existential object conforming to P, the immutability of the method will be erased:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span> c: <span style="color: #703daa" class="">AnyObject</span> & <span style="color: #4f8187" class="">P</span> = <span style="color: #4f8187" class="">C</span>()</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: rgb(0, 132, 0);" class=""><span style="text-decoration: underline ; color: #4f8187" class="">c</span><span style="" class="">.f(</span><span style="color: #272ad8" class="">1</span><span style="" class="">) </span>// </span><font color="#ff2600" class="">Cannot use mutating member on immutable value: 'c' is a 'let' constant</font></div></div><div class=""><br class=""></div><div class="">A generic context has the same issue:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><span style="font-family: Menlo; font-size: 11px; color: rgb(186, 45, 162);" class="">func</span><font face="Menlo" class=""><span style="font-size: 11px;" class=""> f<T: </span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">AnyObject</span><font face="Menlo" class=""><span style="font-size: 11px;" class=""> & </span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(79, 129, 135);" class="">P</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">>(</span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(186, 45, 162);" class="">_</span><font face="Menlo" class=""><span style="font-size: 11px;" class=""> arg: </span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(79, 129, 135);" class="">T</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">)-> </span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Int</span><font face="Menlo" class=""><span style="font-size: 11px;" class=""> { </span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(186, 45, 162);" class="">return</span> <span style="font-family: Menlo; font-size: 11px; text-decoration: underline;" class="">a</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">rg.f(</span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(39, 42, 216);" class="">1</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">) } </span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(0, 132, 0);" class="">// </span><font color="#ff2600" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">Cannot use mutating member on immutable value: ‘arg' is a 'let' constant</span></font></font></div></div><div class=""><br class=""></div><div class=""><div class=""><b class="">My question: </b></div><div class=""><br class=""></div><div class="">Is it too much work to preserve method non-mutability in in these cases?</div></div><div class=""><br class=""></div><div class=""><div class="">The workaround I am using is this:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">protocol</span><span style="" class=""> Q: </span><span style="color: #703daa" class="">class, P </span><span style="" class="">{ </span><span style="color: #ba2da2" class="">func</span><span style="" class=""> f(</span><span style="color: #ba2da2" class="">_</span><span style="" class=""> x: </span><span style="color: #703daa" class="">Int</span><span style="" class="">) -> </span><span style="color: #703daa" class="">Int</span><span style="" class=""> } </span>// 'Refine' it to be non-mutating.</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class="">extension<span style="" class=""> </span><span style="color: #4f8187" class="">C</span><span style="" class="">: </span><span style="color: #4f8187" class="">Q</span><span style="" class=""> {}</span></div></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><span style="" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(0, 132, 0);" class="">// Now these work:</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="color: #ba2da2" class="">let</span> c: <span style="color: #4f8187" class="">Q</span> = <span style="color: #4f8187" class="">C</span>()</div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="color: #4f8187" class="">c</span><span style="" class="">.</span><span style="color: #31595d" class="">f</span><span style="" class="">(</span><span style="color: #272ad8" class="">1</span><span style="" class="">) </span>// OK</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="color: #ba2da2" class="">func</span> f<T: <span style="color: #4f8187" class="">Q</span>>(<span style="color: #ba2da2" class="">_</span> arg: <span style="color: #4f8187" class="">T</span>)-> <span style="color: #703daa" class="">Int</span> { <span style="color: #ba2da2" class="">return</span> arg.<span style="color: #31595d" class="">f</span>(<span style="color: #272ad8" class="">1</span>) } <span style="color: #008400" class="">// OK</span></div></div><div class=""><br class=""></div><div class="">This workaround creates a lot of duplication and is hard to maintain. It is not something that I do often, but when I do, it is pretty annoying. </div><div class=""><br class=""></div><div class=""><b class="">Supplemental questions:</b></div><div class=""><br class=""></div><div class="">Have you guys ever ran into this?</div></div><div class="">Is there already a bug tracking this? </div><div class=""><br class=""></div><div class=""><br class=""></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></body></html>