<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="">Thanks for putting these thoughts together, Jordan! Some additional comments inline.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Aug 2, 2017, at 5:08 PM, Jordan Rose &lt;<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>&gt; 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="">David Hart&nbsp;<a href="https://twitter.com/dhartbit/status/891766239340748800" class="">recently asked on Twitter</a>&nbsp;if there was a good way to add Decodable support to somebody else's class. The short answer is "no, because you don't control all the subclasses", but David already understood that and wanted to know if there was anything working to mitigate the problem. So I decided to write up a long email about it instead. (Well, actually I decided to write a short email and then failed at doing so.)<div class=""><br class=""></div><div class=""><b class="">The Problem</b></div><div class=""><br class=""></div><div class="">You can add Decodable to someone else's struct today with no problems:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">extension<span style="" class=""> </span><span style="color: rgb(79, 129, 135);" class="">Point</span><span style="" class="">: </span><span style="color: rgb(112, 61, 170);" class="">Decodable</span><span style="" class=""> {</span></font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; <span style="color: #ba2da2" class="">enum</span> CodingKeys: <span style="color: #703daa" class="">String</span>, <span style="color: #703daa" class="">CodingKey</span> {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> x</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> y</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; }</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; <span style="color: #ba2da2" class="">public</span> <span style="color: #ba2da2" class="">init</span>(from decoder: <span style="color: #703daa" class="">Decoder</span>) <span style="color: #ba2da2" class="">throws</span> {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> container = <span style="color: #ba2da2" class="">try</span> decoder.<span style="color: #3e1e81" class="">container</span>(keyedBy: <span style="color: #4f8187" class="">CodingKeys</span>.<span style="color: #ba2da2" class="">self</span>)</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> x = <span style="color: #ba2da2" class="">try</span> container.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #703daa" class="">Double</span>.<span style="color: #ba2da2" class="">self</span>, forKey: .<span style="color: #31595d" class="">x</span>)</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> y = <span style="color: #ba2da2" class="">try</span> container.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #703daa" class="">Double</span>.<span style="color: #ba2da2" class="">self</span>, forKey: .<span style="color: #31595d" class="">y</span>)</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">self</span>.<span style="color: #ba2da2" class="">init</span>(x: x, y: y)</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; }</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">}</font></div></blockquote><br class=""><div class="">But if Point is a (non-final) class, then this gives you a pile of errors:</div><div class=""><br class=""></div><div class="">- init(from:) needs to be 'required' to satisfy a protocol requirement. 'required' means the initializer can be invoked dynamically on subclasses. Why is this important? Because someone might write code like this:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class=""><span style="color: #ba2da2" class="">func</span> decodeMe&lt;Result: <span style="color: #703daa" class="">Decodable</span>&gt;() -&gt; <span style="color: #703daa" class="">Result</span> {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; <span style="color: #ba2da2" class="">let</span> decoder = getDecoderFromSomewhere()</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; <span style="color: #ba2da2" class="">return</span> <span style="color: #703daa" class="">Result</span>(from: decoder)</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">}</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class=""><span style="color: #ba2da2" class="">let</span> specialPoint: <span style="color: #703daa" class="">VerySpecialSubclassOfPoint</span> = decodeMe()</font></div></blockquote><br class=""><div class="">…and the compiler can't stop them, because&nbsp;VerySpecialSubclassOfPoint is a Point, and Point is Decodable, and therefore&nbsp;VerySpecialSubclassOfPoint is Decodable. A bit more on this later, but for now let's say that's a sensible requirement.</div><div class=""><br class=""></div><div class="">- init(from:) also has to be a 'convenience' initializer. That one makes sense too—if you're outside the module, you can't necessarily see private properties, and so of course you'll have to call another initializer that can.</div><div class=""><br class=""></div><div class="">But once it's marked 'convenience' and 'required' we get "'required' initializer must be declared directly in class 'Point' (not in an extension)", and that defeats the whole purpose. Why this restriction?</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">The Semantic Reason</b></div><div class=""><b class=""><br class=""></b></div><div class="">The initializer is 'required', right? So all subclasses need to have access to it. But the implementation we provided here might not make sense for all subclasses—what if&nbsp;VerySpecialSubclassOfPoint doesn't have an 'init(x:y:)' initializer? Normally, the compiler checks for this situation and makes the subclass reimplement the 'required' initializer…but that only works if the 'required' initializers are all known up front. So it can't allow this new 'required' initializer to go by, because someone might try to call it dynamically on a subclass. Here's a dynamic version of the code from above:</div><div class=""><br class=""></div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class=""><span style="color: rgb(186, 45, 162);" class="">func</span>&nbsp;decodeDynamic(<span style="color: rgb(186, 45, 162);" class="">_</span>&nbsp;pointType:&nbsp;<span style="color: rgb(112, 61, 170);" class="">Point</span>.Type) -&gt;&nbsp;<span style="color: rgb(112, 61, 170);" class="">Point</span>&nbsp;{</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp;&nbsp;<span style="color: rgb(186, 45, 162);" class="">let</span>&nbsp;decoder = getDecoderFromSomewhere()</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp;&nbsp;<span style="color: rgb(186, 45, 162);" class="">return</span>&nbsp;pointType.<span style="color: rgb(186, 45, 162);" class="">init</span>(from: decoder)</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">}</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class=""><span style="color: rgb(186, 45, 162);" class="">let</span>&nbsp;specialPoint = decodeDynamic(VerySpecialSubclassOfPoint.<span style="color: rgb(186, 45, 162);" class="">self</span>)</font></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">The Implementation Reason</b></div><div class=""><b class=""><br class=""></b></div><div class="">'required' initializers are like methods: they may require dynamic dispatch. That means that they get an entry in the class's dynamic dispatch table, commonly known as its <i class="">vtable</i>. Unlike Objective-C method tables, vtables aren't set up to have entries arbitrarily added at run time.</div><div class=""><br class=""></div><div class="">(Aside: This is one of the reasons why non-@objc methods in Swift extensions can't be overridden; if we ever lift that restriction, it'll be by using a separate table and a form of dispatch similar to objc_msgSend. I sent a proposal to swift-evolution about this last year but there wasn't much interest.)</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">The Workaround</b></div><div class=""><b class=""><br class=""></b></div><div class="">Today's answer isn't wonderful, but it does work: write a wrapper struct that conforms to Decodable instead:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class=""><span style="color: rgb(186, 45, 162);" class="">struct</span> DecodedPoint: <span style="color: rgb(112, 61, 170);" class="">Decodable</span> {</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; <span style="color: #ba2da2" class="">var</span> value: <span style="color: #4f8187" class="">Point</span></font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; <span style="color: #ba2da2" class="">enum</span> CodingKeys: <span style="color: #703daa" class="">String</span>, <span style="color: #703daa" class="">CodingKey</span> {</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> x</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> y</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; }</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; <span style="color: #ba2da2" class="">public</span> <span style="color: #ba2da2" class="">init</span>(from decoder: <span style="color: #703daa" class="">Decoder</span>) <span style="color: #ba2da2" class="">throws</span> {</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> container = <span style="color: #ba2da2" class="">try</span> decoder.<span style="color: #3e1e81" class="">container</span>(keyedBy: <span style="color: #4f8187" class="">CodingKeys</span>.<span style="color: #ba2da2" class="">self</span>)</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> x = <span style="color: #ba2da2" class="">try</span> container.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #703daa" class="">Double</span>.<span style="color: #ba2da2" class="">self</span>, forKey: .<span style="color: #31595d" class="">x</span>)</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> y = <span style="color: #ba2da2" class="">try</span> container.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #703daa" class="">Double</span>.<span style="color: #ba2da2" class="">self</span>, forKey: .<span style="color: #31595d" class="">y</span>)</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">self</span>.<span style="color: #4f8187" class="">value</span> = <span style="color: #4f8187" class="">Point</span>(x: x, y: y)</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; }</font></div></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">}</font></div></div></blockquote><div class=""><br class=""></div><div class="">This doesn't have any of the problems with inheritance, because it only handles the base class, Point. But it makes everywhere else a little less convenient—instead of directly encoding or decoding Point, you have to use the wrapper, and that means no implicitly-generated Codable implementations either.</div><div class=""><br class=""></div><div class="">I'm not going to spend more time talking about this, but it is the officially recommended answer at the moment. You can also just have all your own types that contain points manually decode the 'x' and 'y' values and then construct a Point from that.</div></div></div></blockquote><div>I would actually take this a step further and recommend that <i class="">any</i>&nbsp;time you intend to extend someone else’s type with <font face="SFMono-Regular" class="">Encodable</font> or <font face="SFMono-Regular" class="">Decodable</font>, you should almost certainly write a wrapper struct for it instead, unless you have reasonable guarantees that the type will <i class="">never</i>&nbsp;attempt to conform to these protocols on its own.</div><div><br class=""></div><div>This might sound extreme (and inconvenient), but Jordan mentions the issue here below in&nbsp;<b class="">The Dangers of Retroactive Modeling</b><span class="">. Any time you conform a type which does not belong to you to a protocol, you make a decision about its behavior where you might not necessarily have the "right" to — if the type later adds conformance to the protocol itself (e.g. in a library update), your code will no longer compile, and you’ll have to remove your own conformance. In most cases, that’s fine, e.g., there’s not much harm done in dropping your custom <font face="SFMono-Regular" class="">Equatable</font> conformance on some type if it starts adopting it on its own. The real risk with <font face="SFMono-Regular" class="">Encodable</font> and <font face="SFMono-Regular" class="">Decodable</font> is that unless you don’t care about backwards/forwards compatibility, the <i class="">implementations of these conformances are forever</i>.</span></div><div><span class=""><br class=""></span></div><div>Using <font face="SFMono-Regular" class="">Point</font> here as an example, it’s not unreasonable for <font face="SFMono-Regular" class="">Point</font> to eventually get updated to conform to <font face="SFMono-Regular" class="">Codable</font>. It’s also not unreasonable for the implementation of <font face="SFMono-Regular" class="">Point</font> to adopt the default conformance, i.e., get encoded as <font face="SFMono-Regular" class="">{"x": …, "y": …}</font>. This form might not be the most compact, but it leaves room for expansion (e.g. if <font face="SFMono-Regular" class="">Point</font> adds a <font face="SFMono-Regular" class="">z</font> field, which might also be reasonable, considering the type doesn’t belong to you). If you update your library dependency with the new <font face="SFMono-Regular" class="">Point</font> class and have to drop the conformance you added to it directly, you’ve introduced a backwards and forwards compatibility concern: all new versions of your app now encode and decode a new archive format, which now requires migration. Unless you don’t care about other versions of your app, you’ll have to deal with this:</div><div><ol class="MailOutline"><li class="">Old versions of your app which users may have on their devices cannot read archives with this new format</li><li class="">New versions of your app cannot read archives with the old format</li></ol><div class=""><br class=""></div><div class="">Unless you don’t care for some reason, you will now have to write the wrapper struct, to either</div><div class=""><ol class="MailOutline"><li class="">Have new versions of your app attempt to read old archive versions and migrate them forward (leaving old app versions in the dust), or</li><li class="">Write all new archives with the old format so old app versions can still read archives written with newer app versions, and vice versa</li></ol><div class=""><br class=""></div></div><div class="">Either way, you’ll need to write some wrapper to handle this; it’s significantly safer to do that work up front on a type which you <i class="">do</i>&nbsp;control (and safely allow <font face="SFMono-Regular" class="">Point</font> to change out underneath you transparently), rather than potentially end up between a rock and a hard place later on because a type you don’t own changes out from under you.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><b class="">Future Direction: 'required' + 'final'</b></div><div class=""><b class=""><br class=""></b></div><div class="">One language feature we could add to make this work is a 'required' initializer that is also 'final'. Because it's 'final', it wouldn't have to go into the dynamic dispatch table. But because it's 'final', we have to make sure its implementation works on all subclasses. For that to work, it would only be allowed to call other 'required' initializers…which means you're still stuck if the original author didn't mark anything 'required'. Still, it's a safe, reasonable, and contained extension to our initializer model.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">Future Direction: runtime-checked convenience initializers</b></div><div class=""><b class=""><br class=""></b></div><div class="">In most cases you don't care about hypothetical subclasses or invoking init(from:) on some dynamic Point type. If there was a way to mark init(from:) as something that was always available on subclasses, but dynamically checked to see if it was okay, we'd be good. That could take one of two forms:</div><div class=""><br class=""></div><div class="">- If 'self' is not Point itself, trap.</div><div class="">- If 'self' did not inherit or override all of Point's designated initializers, trap.</div><div class=""><br class=""></div><div class="">The former is pretty easy to implement but not very extensible. The latter seems more expensive: it's information we already check in the compiler, but we don't put it into the runtime metadata for a class, and checking it at run time requires walking up the class hierarchy until we get to the class we want. This is all predicated on the idea that this is rare, though.</div><div class=""><br class=""></div><div class="">This is a much more intrusive change to the initializer model, and it's turning a compile-time check into a run-time check, so I think we're less likely to want to take this any time soon.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">Future Direction: Non-inherited conformances</b></div><div class=""><b class=""><br class=""></b></div><div class="">All of this is only a problem because people might try to call init(from:) on a subclass of Point. If we said that subclasses of Point weren't automatically Decodable themselves, we'd avoid this problem. This sounds like a terrible idea but it actually doesn't change very much in practice. Unfortunately, it's also a very complicated and intrusive change to the Swift protocol system, and so I don't want to spend more time on it here.</div><div class=""><b class=""><br class=""></b></div><div class=""><b class=""><br class=""></b></div><div class=""><b class="">The Dangers of Retroactive Modeling</b></div><div class=""><b class=""><br class=""></b></div><div class="">Even if we magically make this all work, however, there's still one last problem: <i class="">what if two frameworks do this?</i> Point can't conform to Decodable in two different ways, but neither can it just pick one. (Maybe one of the encoded formats uses "dx" and "dy" for the key names, or maybe it's encoded with polar coordinates.) There aren't great answers to this, and it calls into question whether the struct "solution" at the start of this message is even sensible.</div><div class=""><br class=""></div><div class="">I'm going to bring this up on swift-evolution soon as part of the Library Evolution discussions (there's a very similar problem if the library that owns Point decides to make it Decodable too), but it's worth noting that the wrapper struct solution doesn't have this problem.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Whew! So, that's why you can't do it. It's not a very satisfying answer, but it's one that falls out of our compile-time safety rules for initializers. For more information on this I suggest checking out my write-up of some of our&nbsp;<a href="https://github.com/apple/swift/blob/master/docs/InitializerProblems.rst" class="">initialization model problems</a>. And I plan to write another email like this to discuss some solutions that are actually doable.</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><div class="">P.S. There's a reason why Decodable uses an initializer instead of a factory-like method on the type but I can't remember what it is right now. I think it's something to do with having the right result type, which would have to be either 'Any' or an associated type if it wasn't just 'Self'. (And if it is 'Self' then it has all the same problems as an initializer and would require extra syntax.) Itai would know for sure.</div></div></div></blockquote></div>To give background on this — the protocols originally had factory initializers in mind for this (to allow for object replacement and avoid some of these issues), but without a "real" factory initializer pattern like we’re discussing here, the problems with this approach were intractable (all due to subclassing issues).<div class=""><font face="SFMono-Regular" class=""><br class=""></font></div><div class=""><font face="SFHello-Regular" class="">An initializer pattern like </font><font face="SFMono-Regular" class="">static func decode(from: Decoder) throws -&gt; ???</font><font face="SFHello-Regular" class=""> has a few problems</font><div class=""><ol class="MailOutline"><li class="">The return type is one consideration. If we allow for an associated type representing to the return type, subclasses cannot override the associated type to return something different. This makes object replacement impossible in situations which use subclassing. The only reasonable thing is to return <font face="SFMono-Regular" class="">Self</font>&nbsp;(which would allow for returning instances of self, or of subclasses). (We could return <font face="SFMono-Regular" class="">Any</font>, but that defeats the entire purpose of having a type-safe API to begin with; we want to avoid the dynamic casting altogether.)</li><li class="">Even if we return <font face="SFMono-Regular" class="">Self</font>, this method cannot be overridden by subclasses:</li><ul class=""><li class="">If implemented as <font face="SFMono-Regular" class="">static func decode(from: Decoder) throws -&gt; Self</font><font face="SFHello-Regular" class="">, the method clearly cannot be overridden in a subclass, as it is a static method</font></li><li class=""><font face="SFHello-Regular" class="">The method cannot be implemented as </font><font face="SFMono-Regular" class="">class func decode(from: Decoder) throws -&gt; Self</font><font face="SFHello-Regular" class=""> on a non-final class:</font></li><ul class=""><li class=""><span style="font-family: SFMono-Regular;" class="">protocol Foo {</span></li></ul><li class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><span style="font-family: SFMono-Regular;" class="">&nbsp; &nbsp; static func create() -&gt; Self</span></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><span style="font-family: SFMono-Regular;" class="">}</span></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><span style="font-family: SFMono-Regular;" class=""><br class=""></span><span style="font-family: SFMono-Regular;" class="">class Bar : Foo {<br class=""></span><span style="font-family: SFMono-Regular;" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family: SFMono-Regular;" class="">class func create() -&gt; Bar { // method 'create()' in non-final class 'Bar' must return 'Self' to conform to protocol 'Foo'<br class=""></span><span style="font-family: SFMono-Regular;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: SFMono-Regular;" class="">return Bar()<br class=""></span><span style="font-family: SFMono-Regular;" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family: SFMono-Regular;" class="">}<br class=""></span><font face="SFMono-Regular" class="">}</font></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><font face="SFMono-Regular" class=""><br class=""></font></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""></blockquote></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><blockquote style="font-family: Helvetica; margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="font-family: Helvetica; margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="font-family: Helvetica; margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="font-family: Helvetica; margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="font-family: Helvetica; margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><blockquote style="font-family: Helvetica; margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote></div></li><ul class=""><li class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">protocol Foo {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">&nbsp; &nbsp; static func create() -&gt; Self</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">}</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><font face="SFMono-Regular" class=""><br class=""></font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">class Bar : Foo {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">&nbsp; &nbsp; class func create() -&gt; Self {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">&nbsp; &nbsp; &nbsp; &nbsp; return Bar() // cannot convert return expression of type 'Bar' to return type 'Self'</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">&nbsp; &nbsp; }</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="SFMono-Regular" class="">}</font></div><div class=""><span style="font-family: SFMono-Regular;" class=""><br class=""></span></div><div class=""><br class=""></div></li><li class=""><span style="font-family: SFMono-Regular;" class="">protocol Foo {</span><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""></div></li></ul><li class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><font face="SFMono-Regular" class="">&nbsp;&nbsp; &nbsp;static func create() -&gt; Self</font></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><font face="SFMono-Regular" class="">}</font></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><font face="SFMono-Regular" class=""><br class=""></font><font face="SFMono-Regular" class="">class Bar : Foo {<br class=""></font><font face="SFMono-Regular" class="">&nbsp; &nbsp; class func create() -&gt; Self {<br class=""></font><font face="SFMono-Regular" class="">&nbsp; &nbsp; &nbsp; &nbsp; return Bar() as! Self // error: 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'Bar'?; warning: forced cast of 'Bar' to same type has no effect; error: cannot convert return of expression type 'Bar' to return type 'Self'<br class=""></font><font face="SFMono-Regular" class="">&nbsp; &nbsp; }<br class=""></font><font face="SFMono-Regular" class="">}</font></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><font face="SFMono-Regular" class=""><br class=""></font></blockquote></div></li><ul class=""><li class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><font face="SFMono-Regular" class="">final class Bar : Foo {<br class=""></font><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><font face="SFMono-Regular" class="">&nbsp; &nbsp;&nbsp;class func create() -&gt; Bar { // no problems<br class=""></font><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><font face="SFMono-Regular" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return Bar()<br class=""></font><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote><font face="SFMono-Regular" class="">&nbsp; &nbsp;&nbsp;}<br class="">}</font></li></ul><li class="">This means that we either allow adoption of these protocols on <font face="SFMono-Regular" class="">final</font> classes only (which, again, defeats the whole purpose!), or, that every class which implements these protocols has to have knowledge about all of its potential subclasses and their implementations of these protocols. This is prohibitive as well.</li></ul><li class="">Even if it were possible to subclass these types of methods, they don’t follow the regular initializer pattern. In order to construct an instance of a subclass, you need to be able to call a superclass initializer. But these methods are not initializers; even if you call super’s factory initializer, there’s noting you can do with the returned instance of the superclass; unlike in ObjC, there’s no super- or self-reassignment (in general), so classes would have to follow a completely different (and awkward) pattern of creating an instance of the superclass, initializing from that instance in a separate initializer (e.g. <font face="SFMono-Regular" class="">self.init(superInstance)</font>), and also setting decoded properties</li></ol><div class=""><br class=""></div></div></div><div class="">Overall, the lack of a true factory initializer pattern prevented us from doing something like this, and we took the regular initializer approach.</div></body></html>