<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 Aug 2, 2017, at 10:11 PM, Mike Sanderson &lt;<a href="mailto:m@mikesand.com" class="">m@mikesand.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">It seems that this discussion got sidetracked from the original proposal, that aimed to provide more visibility about default implementation for protocols, to the merits of writing functionality for classes and structs in same-file extensions.&nbsp;</div><div class=""><br class=""></div><div class="">1. `default` for Protocols&nbsp;</div><div class=""><br class=""></div><div class="">First, the issue the original proposal wants to solve is real-- knowing what methods have default implementations and therefore what you actually need to implement to conform to a complex protocol can get complex. (Chris Eidhof&nbsp;has a great extended discussion about conforming to `Collection` in Advanced Swift that covers this in detail. It's advanced.)&nbsp;</div><div class=""><br class=""></div><div class="">My understanding of the proposal is that marking a method `default` would force the protocol author to write a default method, and provide a label for anyone reading the protocol that this method has a default implementation.&nbsp;</div><div class=""><br class=""></div><div class="">However, if non-default methods can still have protocol extensions (the alternative of not allowing this would be a huge restriction on protocol extensions) then after these extensions are written, the methods would have default implementations but not be marked default-- we're back to the&nbsp;original problem. This would be whenever the person writing the extension can't modify the protocol to add default, which is probably often.&nbsp;</div></div></div></blockquote><div><br class=""></div><div>Good point. It would indeed take extra care to make sure that all requirements are properly annotated.</div><div>Another way of doing it would be to allow protocols to conform to other protocols as opposed to inherit from them. When a protocol inherits from another protocol, it gets the requirements from the parent protocol added to its own requirements. If a protocol could specify conformance to another protocol, that would mean that the parent protocol's requirements need to be satisfied by extensions of the child protocol. The compiler can emit the usual errors to make sure that the child protocol does indeed cover all requirements of the parent protocol.</div><div>With this feature a single protocol with default-implemented requirements could be split into two protocols and the main one would conform to (instead of inheriting from) the other one.</div><div>Here's an example <a href="https://gist.github.com/technogen-gg/065e088b12f2aef44f11d84c583c3368" class="">https://gist.github.com/technogen-gg/065e088b12f2aef44f11d84c583c3368</a></div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">So while I agree with the issue, I'm not sure adding a `default` label solves it. Maybe a better way to link to any protocol extensions from the protocol declaration, or better way to see where a conforming type gets its conforming methods, but these might be Xcode features. &nbsp; &nbsp;</div></div></div></blockquote><div><br class=""></div><div>Xcode could surely make it easier to conform to protocols, but that wouldn't help the author make sure that all requirements of a protocol that are meant to be default-implemented are default-implemented.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">2. Same-file extensions</div><div class=""><br class=""></div><div class="">The issue of using same-file extensions to organize code probably should be discussed as it's own topic. My understanding is it first emerged as a suggestion from 2014 WWDC labs specifically because Swift did not have pragma marks (<a href="https://www.natashatherobot.com/using-swift-extensions/" target="_blank" class="">https://www.natashatherobot.<wbr class="">com/using-swift-extensions/</a>, <a href="https://stackoverflow.com/a/24069206/4474705" target="_blank" class="">https://stackoverflow.com/a/<wbr class="">24069206/4474705</a>). For self-contained, purely additive protocol conformance I think it makes sense, such as for adding `CustomDebugStringConvertable`<wbr class="">. But it always seemed weird to me for things like UITableViewDataSource on a view controller that exists to support a table view-- even if all the methods for the delegate are there, they will rely on access to stored properties for the model, rely on helper methods, rely on lifecycle functions to have called `registerClass:<wbr class="">forReuseIdentifer` etc. The extension is just for grouping methods, which is better than nothing, but which it does under the guise of a language feature.&nbsp;</div><div class=""><br class=""></div><div class="">Still, this style of extensions is widely used. I'm not sure if same-file extensions needs language-level endorsement and codification, or if it's a programming style/usage issue and people should argue about it on their own time. But I think this thread shows regardless it's an open question.&nbsp;</div></div></div></blockquote><div><br class=""></div><div>The main benefit of same-file extensions is that it's possible for the compiler to merge their content into the type definition before emitting it. This would allow things like stored properties in extensions possible without any overhead or dynamic dispatch.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">Mike Sanderson</div><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Aug 2, 2017 at 11:44 AM, Gor Gyolchanyan via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class="m_-1465804553045819648gmail-"><blockquote type="cite" class=""><div class="">On Aug 2, 2017, at 6:18 PM, Tino Heth &lt;<a href="mailto:2th@gmx.de" target="_blank" class="">2th@gmx.de</a>&gt; wrote:</div><br class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class=""><div class="">Hi Gor,</div><div class=""><br class=""></div><div class="">[I'll continue to answer below, but that wont help you with your proposal…]</div><div class=""><br class=""></div><div class="">The question is wether this</div><div class=""><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><font color="#b92d5d" class="">protocol</font>&nbsp;<font color="#4f7a28" class="">Equatable</font>&nbsp;{</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#b92d5d" class="">static</font>&nbsp;<font color="#b92d5d" class="">func</font>&nbsp;== (_ some:&nbsp;<font color="#b92d5d" class="">Self</font>, _ other:&nbsp;<font color="#b92d5d" class="">Self</font>) -&gt;&nbsp;<font color="#4f7a28" class="">Bool</font></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#b92d5d" class="">default</font>&nbsp;<font color="#b92d5d" class="">static</font>&nbsp;<font color="#b92d5d" class="">func</font>&nbsp;!= (_ some:&nbsp;<font color="#b92d5d" class="">Self</font>, _ other:&nbsp;<font color="#b92d5d" class="">Self</font>) -&gt;&nbsp;<font color="#4f7a28" class="">Bool</font></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class="">}</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><font color="#b92d5d" class="">extension</font>&nbsp;<font color="#4f7a28" class="">Equatable</font>&nbsp;{</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">        </span></font><font color="#b92d5d" face="Menlo" class="">static</font><span style="font-family:Menlo" class="">&nbsp;</span><font color="#b92d5d" face="Menlo" class="">func</font><span style="font-family:Menlo" class="">&nbsp;!= (_ some:&nbsp;</span><font color="#9a244f" style="font-family:Menlo" class="">Self</font><span style="font-family:Menlo" class="">, _ other:&nbsp;</span><font color="#9a244f" style="font-family:Menlo" class="">Self</font><span style="font-family:Menlo" class="">) -&gt;&nbsp;</span><font color="#4f7a28" face="Menlo" class="">Bool</font><font face="Menlo" class="">&nbsp;{</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">                </span><b class="">[<font color="#4d22b3" class="">Your Code Here]</font></b></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div></div><div class="">is better than</div><div class=""><br class=""></div><div class=""><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><font color="#b92d5d" class="">protocol</font>&nbsp;<font color="#4f7a28" class="">Equatable</font>&nbsp;{</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#b92d5d" class="">static</font>&nbsp;<font color="#b92d5d" class="">func</font>&nbsp;== (_ some:&nbsp;<font color="#b92d5d" class="">Self</font>, _ other:&nbsp;<font color="#b92d5d" class="">Self</font>) -&gt;&nbsp;<font color="#4f7a28" class="">Bool</font></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">        </span></font><font color="#b92d5d" face="Menlo" class="">static</font><span style="font-family:Menlo" class="">&nbsp;</span><font color="#b92d5d" face="Menlo" class="">func</font><span style="font-family:Menlo" class="">&nbsp;!= (_ some:&nbsp;</span><font color="#9a244f" style="font-family:Menlo" class="">Self</font><span style="font-family:Menlo" class="">, _ other:&nbsp;</span><font color="#9a244f" style="font-family:Menlo" class="">Self</font><span style="font-family:Menlo" class="">) -&gt;&nbsp;</span><font color="#4f7a28" face="Menlo" class="">Bool</font><font face="Menlo" class="">&nbsp;{</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">                </span><b class="">[<font color="#4d22b3" class="">Your Code Here]</font></b></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class=""><br class=""></font></div><div style="background-color:rgb(255,255,255)" class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font class="">I don't think so, and therefore, I don't want to add a new keyword (or, more precise, a new meaning for an existing keyword).</font></div></div><div class="">Both solutions could coexist, but I doubt that implementation inside protocol body leaves enough room for "default func".</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I'll reiterate: the problem with the inline solution is that it forces all code to be bunched up in a single place and sacrifices readability.</div><span class="m_-1465804553045819648gmail-"><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class="">- Tino</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><div class="">Fileprivate has been there for years, it just was called private — and because the "church of extensions" ;-) has been so powerful, we finally ended up with what we have now.</div></div></div></div></blockquote><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><br class=""></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">Yes, I was here. The fact that we started off with private behaving the way it does now is history now. The point stands: extensions in the same file as the type definition have an extra guarantee that enable the compiler to provide extra features based on that: the guarantee that the extension and the type definition will always be visible simultaneously, thus, implicitly merging the extension into the type definition is possible. It's not possible to do in any other way, because a file is the only unit of compilation that's more-or-less guaranteed to be atomically parsed. A module is separated into files, which can be compiled into objects separately, making it impossible for the compiler to know if any extension in any of the other files will change the layout of the type.</div></div></div></div></blockquote><div class="">The compiler won't care where if a method is defined in the type declaration, or in an extension in the same file.</div><div class="">What extra guarantee could those extensions offer?</div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">The extra guarantee that all non-same-file extensions don't have: the guarantee that the extension can be deterministically merged with the type definition before the type definition is emitted.</div><span class="m_-1465804553045819648gmail-"><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class="">They are recommended in style guides, influencers blog about them, and they motivated a ridiculous complex change in the access rights system. Yet I haven't seen any evidence that they offer real benefit.</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class=""><div class="">Extensions are a tool for decentralizing code. There are some critical limits on extensions that make main type definition subject to unavoidable bloating (required and designated initializers, stored properties, the deinitializer, and open methods), but everything else is a prime candidate for decentralizing. Putting as little code as possible into the type definition and semantically grouping the implementation into extensions improves readability and maintainability dramatically.</div></div></div></div></blockquote><div class="">The thing is: This is just a claim that gets repeated over and over. There is no proof, and I even don't know a single study on that topic.</div></div></div></div></blockquote><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><br class=""></div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline" class="">Take a look at this article:&nbsp;</span><a href="https://en.wikipedia.org/wiki/Separation_of_concerns" target="_blank" class="">https://en.wikipedia.<wbr class="">org/wiki/Separation_of_concern<wbr class="">s</a></div></div></div></blockquote><div class="">There's nothing about Swift, neither about extensions, in this article.</div><div class="">I don't want to start throwing around buzzwords, but there's also&nbsp;<a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself" target="_blank" class="">https://en.wikipedia.org/<wbr class="">wiki/Don%27t_repeat_yourself</a></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">The Don't Repeat Yourself principle states that providing generic solutions to domains of problems is superior to providing largely similar solutions to specific problems. If anything, separating related bunches of code helps reduce extra work by localizing the code in a way that makes refactoring and debugging easier.</div><div class="">The separation of concerns is a well-known software design and implementation principle whereby code quality (which encompasses readability, maintainability, extensibility, portability) are improved through strict separation of logically unrelated (or loosely related) parts of the code.&nbsp;</div><div class=""><div class="m_-1465804553045819648gmail-h5"><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class="">Extensions are great for adding useful helpers to existing types, and still allow you to selectively expose details of your own classes — but most people seem to ignore those options and focus on something can be done better with plain old comments.</div></div></div></div></div></blockquote><div class=""><br class=""></div>Relying on comments for invariants and preconditions is a poor design decision, because there's no way of enforcing them and the whole integrity of the code is thrown at the mercy of a human's carefulness (which is a horrible fate to befall upon any code). By writing the code in such a way that makes it impossible to be misused (by way of compiler enforcement), the code becomes resilient and no amount of clumsy usage can lead to incredibly obscure bugs that would take a week of debugging to catch.</div></div></blockquote><div class="">But extensions are no tool to do so: They have no features that offer any protection, exactly like comments — they are just more typing and don't show up properly in Xcode.</div><div class=""><br class=""></div><div class=""><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">import</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>UIKit</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""></span><br class=""></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">class</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>MyViewController:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">UIView<wbr class="">Controller</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""></span><br class=""></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)" class=""><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">extension</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(79,129,135)" class="">MyViewController</span><span style="font-variant-ligatures:no-common-ligatures" class="">:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures" class="">UI<wbr class="">TableViewDataSource</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""></span><br class=""></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">func</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView(</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">_</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class=""><wbr class="">UITableView</span><span style="font-variant-ligatures:no-common-ligatures" class="">, numberOfRowslnSection:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="">) -&gt;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">return</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(39,42,216)" class="">1</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""></span><br class=""></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">func</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView(</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">_</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class=""><wbr class="">UITableView</span><span style="font-variant-ligatures:no-common-ligatures" class="">, didSelectRowAt:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">IndexPath</span><span style="font-variant-ligatures:no-common-ligatures" class="">) {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(62,30,129)" class="">print</span><span style="font-variant-ligatures:no-common-ligatures" class="">(</span><span style="font-variant-ligatures:no-common-ligatures" class="">"Hu, isn't this a delegate method?"</span><span style="font-variant-ligatures:no-common-ligatures" class="">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""></span><br class=""></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)" class=""><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">extension</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(79,129,135)" class="">MyViewController</span><span style="font-variant-ligatures:no-common-ligatures" class="">:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures" class="">UI<wbr class="">TableViewDelegate</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">func</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView(</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">_</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class=""><wbr class="">UITableView</span><span style="font-variant-ligatures:no-common-ligatures" class="">, numberOfRowsInSection:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="">) -&gt;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">Int<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures" class="">{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">return</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(39,42,216)" class="">99</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""></span><br class=""></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">func</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView(</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">_</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>tableView:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class=""><wbr class="">UITableView</span><span style="font-variant-ligatures:no-common-ligatures" class="">, cellForRowAt indexPath:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">IndexPath</span><span style="font-variant-ligatures:no-common-ligatures" class="">) -&gt;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">UITableViewCell</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">let</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>cell =<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">UITableViewCell</span><span style="font-variant-ligatures:no-common-ligatures" class="">(style: .</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(62,30,129)" class="">default</span><span style="font-variant-ligatures:no-common-ligatures" class="">, reuseIdentifier:<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(209,47,27)" class="">""</span><span style="font-variant-ligatures:no-common-ligatures" class="">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; cell.</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">textLabel</span><span style="font-variant-ligatures:no-common-ligatures" class="">?.</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(112,61,170)" class="">text</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>=<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures" class="">"I should get my data from a datasource"</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)" class="">return</span><span style="font-variant-ligatures:no-common-ligatures" class=""><span class="m_-1465804553045819648gmail-m_-2305407732357103542Apple-converted-space">&nbsp;</span>cell</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">}</span></div></div><div class=""><br class=""></div><div class="">This is perfectly valid Swift, and it is build on extensions — but does it increase the quality of the code?</div><div class="">Same file extensions are nothing but a different pair of parenthesis to surround your code, and since Swift 4, you can shuffle around those delimiters however you like, and it has still the same meaning for the compiler.</div><div class="">They enforce nothing, and so far, I haven't seen any ideas to increase their power.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">The compiler also doesn't stop you from making a wide variety of design choices, a comprehensive list of which can be found here:&nbsp;<a href="https://en.wikipedia.org/wiki/Anti-pattern#Programming" target="_blank" class="">https://en.wikipedia.org<wbr class="">/wiki/Anti-pattern#Programming</a></div><div class="">For instance, have you tried reading the implementation of sin function in glibc? It's a very thick spaghetti code, sprinkled with a bucketful of magic numbers. It's absolutely impossible to comprehend.</div><div class=""><br class=""></div><div class="">Any language limitation should only be implemented if it passes the threshold where the gain of safety and convenience outweighs the loss of flexibility and the cost of implementing the limitation.</div><div class="">In your example, the gain of convenience is much lower than the cost of implementing it and loss of flexibility.</div></div></div></div></blockquote><div class="">What?</div><div class="">I didn't talk about adding limitations, and my example just shows that that "extension-oriented programming" doesn't add safety, just like comments — simply because the compiler strips both kinds of decoration.</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">Your example demonstrated a hypothetical lack of a compiler limitation that would make extensions more convenient and I demonstrated that such a limitation (namely, forcing protocol conformance and implementation of protocol requirements to be in a single extension) would not be a good idea.</div><div class="">Extensions are not decoration. They're at the very least access control tool. Extensions can have private members that are only visible to the extension and all other extensions in the same file. You can put many extensions into separate files and have them all operate on private members without exposing those private members and without having to bunch them all up into one place.</div><span class="m_-1465804553045819648gmail-"><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class="">[sorry for the rant — but I think a critical look at extensions is long overdue: I rarely see someone questioning their role, so basically, we are making important decisions based on pure superstition]</div><div class=""><br class=""></div><div class="">A protocol itself is already a vehicle to group related methods,</div></div></div></div></div></blockquote><div class=""><br class=""></div>A protocol is a vehicle for generic programming and separation of abstractions.</div></div></blockquote><div class="">True — but does that stop a protocol from being a way to group related methods?</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Protocols are not free. They come at a cost of wrapping the object in an existential container and make indirect calls via the witness table. Extensions on value types are free.</div></div></div></div></blockquote></div>All true — but not an answer to the question ;-)</div></div></blockquote><br class=""></span></div><div class="">The answer is no. Extensions are specifically designed to group related methods and they have minimal overhead. Protocols have overhead (even if that overhead is not nearly as much as a class overhead) and serve the purpose of providing polymorphism. Protocols also pollute the global namespace and introduce complexity to the interface, so they also have an overhead of complexity. Extensions do none of those things.</div>Using protocols simply for bunching up related methods is similar to using a bulldozer for digging a hole in a sandbox.<div class=""><br class=""></div></div><br class="">______________________________<wbr class="">_________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailma<wbr class="">n/listinfo/swift-evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>