<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 Jan 19, 2017, at 10:52 PM, rintaro ishizaki 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=""><div dir="ltr" class=""><div class=""><div class="m_2220125713830145999m_-5113574630879694870gmail_msg"><div class="m_2220125713830145999m_-5113574630879694870gmail_msg"><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,"segoe ui",helvetica,arial,sans-serif,"apple color emoji","segoe ui emoji","segoe ui symbol";font-size:16px" class="m_2220125713830145999m_-5113574630879694870gmail_msg">From the perspective of the caller, I think, this behavior is counterintuitive because we use "reference types" with an expectation: the referencing address would never be changed <em class="m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing: border-box;">unless</em> we explicitly replace the object by re-assigning to the variable in call sites, e.g.,</p><div class=""><br class=""></div></div></div></div></div></div></blockquote><div><br class=""></div>Well, there’s no real difficulty here, other than potential user confusion. The ‘self’ parameter for a mutating method is passed inout, so this behaves as if you called a global function with an inout argument. The difference is of course when you pass a non-self inout argument, the compiler requires you to use the explicit & syntax at the call site.</div><div><br class=""></div><div>Is your proposal to ban calls to such mutating methods on a type that is known to be a reference type at compile time altogether? This will create an inconsistency between code that operates on concrete types and code that operates on generic parameters (in the latter case the compiler of course has no way to statically guarantee that the value is not a reference type).</div><div><br class=""></div><div>The last time this quirk came up in internal discussions, the thought some of us had was that it might be worthwhile to prohibit classes from conforming to protocols with mutating requirements altogether. If you think about it, this makes some amount of sense — it seems like it would be quite hard to write code that can operate on both mutable values and mutable references generically, since the latter do not have value semantics:</div><div><br class=""></div><div>var x = y</div><div>x.mutatingProtocolRequirement()</div><div>// did y change too?</div><div><br class=""></div><div>However the discussion sort of fizzled out.</div><div><br class=""></div><div>Perhaps we can resurrect it as a proposal, but the bar is pretty high for removing features at this point, since there’s no actual type soundness issue, just possible confusion.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="m_2220125713830145999m_-5113574630879694870gmail_msg"><div class="m_2220125713830145999m_-5113574630879694870gmail_msg"><div class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-highlight-source-swift m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-highlight m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing:border-box;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,"segoe ui",helvetica,arial,sans-serif,"apple color emoji","segoe ui emoji","segoe ui symbol";font-size:16px"><pre style="box-sizing:border-box;font-family:consolas,"liberation mono",menlo,courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-radius:3px;word-break:normal" class="m_2220125713830145999m_-5113574630879694870gmail_msg"><span class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-pl-k m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing:border-box;color:rgb(167,29,93)">var</span> ref<span class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-pl-k m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing:border-box;color:rgb(167,29,93)">:</span> Foo <span class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-pl-k m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing:border-box;color:rgb(167,29,93)">=</span> <span class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-pl-c1 m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing:border-box;color:rgb(0,134,179)">Foo</span>()<br class="">ref <span class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-pl-k m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing:border-box;color:rgb(167,29,93)">=</span> <span class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-pl-c1 m_2220125713830145999m_-5113574630879694870gmail_msg" style="box-sizing:border-box;color:rgb(0,134,179)">Foo</span>()</pre></div><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,"segoe ui",helvetica,arial,sans-serif,"apple color emoji","segoe ui emoji","segoe ui symbol"" class="m_2220125713830145999m_-5113574630879694870gmail_msg"><a id="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-user-content-default-implementation-for-initializers" class="m_2220125713830145999m_-5113574630879694870m_7219822014521869861m_-8940170682087648544gmail-anchor m_2220125713830145999m_-5113574630879694870gmail_msg" href="https://gist.github.com/rintaro/e9d606e2a6d833a043cf43a9a3e14670#default-implementation-for-initializers" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"></a>Default implementation for initializers</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,"segoe ui",helvetica,arial,sans-serif,"apple color emoji","segoe ui emoji","segoe ui symbol";font-size:16px" class="m_2220125713830145999m_-5113574630879694870gmail_msg">Similar to methods, initializers also have this issue:</p></div></div></div></div></div></blockquote></div>In the specific case of initializers, my opinion here is the opposite in fact — I think assigning to ‘self’ should be permitted in all convenience initializers, even initializers defined directly classes, without the protocol extension trick. Also, we should lower this more efficiently than we do today, without creating a self ‘carcass’ that is allocated and immediately freed, to be replaced by the ‘real’ self.<div class=""><br class=""></div><div class="">We already have something like this in fact, it’s called ‘factory initializers', but it’s not directly exposed through the language. It is possible to import a static method or C function as a convenience initializer on a type. The Dispatch overlay uses this for example — DispatchQueue.init actually calls dispatch_queue_create(), which returns a new instance of the type, and not [[OS_dispatch_queue alloc] init] as you would expect if this was a vanilla Objective-C class. The code that gets generated here is similar to the protocol extension initializer example you show that assigns to ‘self’.</div><div class=""><br class=""></div><div class="">Slava</div></body></html>