<html><body><div>I have nothing against small protocols with a defined purpose, on the contrary I am accustomed to type classes in Haskell which are typically very small.<br></div><div>The problem is that these "default" protocols do not serve a well defined purpose - they only exist to work around a deficiency in expressibility.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>The point about the protocol not being under my control is the following (actually it is more about the extension with the default implementation not being under my control): imagine the protocol and especially the extension with default implementations for methods of that protocol is a third party protocol, i.e. protocol BooType and extension BooType are part of a third party library. In that case I cannot split off the default implementations into sub protocols.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Maybe some concise syntax can be found to bind the existing implementation to the protocol when conforming existing classes or structs to a protocol, like Greg Parker suggested.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>-Thorsten<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div><br>Am 06. Januar 2016 um 10:50 schrieb Xiaodi Wu <xiaodi.wu@gmail.com>:<br><br><div><blockquote type="cite"><div class="msg-quote"><div class="_stretch"><span class="body-text-content">You're quite right: in the worst case, the number of protocols you<br>would need would be linear to the number of methods. It's not the<br>best, I will concede. It does seem to be rather the "Swifty" way,<br>though. At least, if we follow the example of the Swift standard<br>library, it's not discouraged. Consider that the protocol hierarchy<br>for Int already has 26 protocols<br>(<a href="http://blog.krzyzanowskim.com/2015/03/01/swift_madness_of_generic_integer/" data-mce-href="http://blog.krzyzanowskim.com/2015/03/01/swift_madness_of_generic_integer/">http://blog.krzyzanowskim.com/2015/03/01/swift_madness_of_generic_integer/</a>).<br>What harm is there in another 3 or 4, or even 10--provided that each<br>is clearly named, serves a defined purpose, and is composed together<br>in something of a logical way?<br><br>I don't understand your point about controlling the protocol. Perhaps<br>you could explain? As far as I can tell, in my example BooType doesn't<br>need to be under your control or modified. If you extend Bar with<br>DefaultBooType, then (Bar is BooType == true).<br><br><br>On Wed, Jan 6, 2016 at 3:32 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:<br><blockquote type="cite" class="quoted-plain-text">That's a good argument, but I'm not convinced: not only do I have to define</blockquote><blockquote type="cite" class="quoted-plain-text">additional protocols ("DefaultXXX") but in the worst case I have to do this</blockquote><blockquote type="cite" class="quoted-plain-text">for each method declared in my protocol (which makes naming these default</blockquote><blockquote type="cite" class="quoted-plain-text">protocols even worse, because XXX now has to represent the method), i.e.</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">protocol BooType {</blockquote><blockquote type="cite" class="quoted-plain-text">func someBoo()</blockquote><blockquote type="cite" class="quoted-plain-text">func anotherBoo()</blockquote><blockquote type="cite" class="quoted-plain-text">func yetAnotherBoo()</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">when given:</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">struct Foo {</blockquote><blockquote type="cite" class="quoted-plain-text">func someBoo() { print("foo boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">struct Bar {</blockquote><blockquote type="cite" class="quoted-plain-text">func anotherBoo() { print("bar boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">struct Baz {</blockquote><blockquote type="cite" class="quoted-plain-text">func anotherBoo() { print("baz boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">I would have to define all of the following:</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">protocol DefaultBooTypeSomeBoo : BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension DefaultBooTypeSomeBoo {</blockquote><blockquote type="cite" class="quoted-plain-text">func someBoo() { print("some boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">protocol DefaultBooTypeAnotherBoo : BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension DefaultBooTypeAnotherBoo {</blockquote><blockquote type="cite" class="quoted-plain-text">func anotherBoo() { print("another boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">protocol DefaultBooTypeYetAnotherBoo : BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension DefaultBooTypeYetAnotherBoo {</blockquote><blockquote type="cite" class="quoted-plain-text">func yetAnotherBoo() { print("yet another boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">Even worse: if the protocol itself is not under my control I cannot even do</blockquote><blockquote type="cite" class="quoted-plain-text">this (not even for the simple case you demonstrated)!</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">-Thorsten</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">Am 06. Januar 2016 um 09:36 schrieb Xiaodi Wu <xiaodi.wu@gmail.com>:</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">The pattern might exist for some existing classes or structs but it might</blockquote><blockquote type="cite" class="quoted-plain-text">still be useful for new classes or even for some existing ones to provide a</blockquote><blockquote type="cite" class="quoted-plain-text">default implementation.</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">I agree. It could be very useful in certain circumstances, and I agree</blockquote><blockquote type="cite" class="quoted-plain-text">that any proposal that made this no longer possible would be a</blockquote><blockquote type="cite" class="quoted-plain-text">non-starter. I had to think about this point for a bit; I hope I can</blockquote><blockquote type="cite" class="quoted-plain-text">convince you that it would remain possible if overriding methods had</blockquote><blockquote type="cite" class="quoted-plain-text">to use a keyword. The way it would be done would be valid code today,</blockquote><blockquote type="cite" class="quoted-plain-text">and I think after some reflection that it's a superior way of doing</blockquote><blockquote type="cite" class="quoted-plain-text">things even in today's Swift syntax because it's more explicit about</blockquote><blockquote type="cite" class="quoted-plain-text">what's going on.</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">Example:</blockquote><blockquote type="cite" class="quoted-plain-text">Given three existing struct types--</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">struct Foo {</blockquote><blockquote type="cite" class="quoted-plain-text">func boo() { print("foo boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">struct Bar { }</blockquote><blockquote type="cite" class="quoted-plain-text">struct Baz { }</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">We wish to formalize after the fact, giving each type a method boo()</blockquote><blockquote type="cite" class="quoted-plain-text">with a default implementation. Currently, this is valid Swift code--</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">protocol BooType {</blockquote><blockquote type="cite" class="quoted-plain-text">func boo()</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">extension BooType {</blockquote><blockquote type="cite" class="quoted-plain-text">func boo() { print("default boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">extension Foo: BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension Bar: BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension Baz: BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">As you point out rightly, this would be invalid if we had to write</blockquote><blockquote type="cite" class="quoted-plain-text">"override func boo()" in the body of struct Foo. However, this is</blockquote><blockquote type="cite" class="quoted-plain-text">valid Swift code both in today's syntax and if my proposal were to be</blockquote><blockquote type="cite" class="quoted-plain-text">implemented, and it is only one line longer--</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">protocol BooType {</blockquote><blockquote type="cite" class="quoted-plain-text">func boo()</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">protocol DefaultBooType: BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension DefaultBooType {</blockquote><blockquote type="cite" class="quoted-plain-text">func boo() { print("default boo") }</blockquote><blockquote type="cite" class="quoted-plain-text">}</blockquote><blockquote type="cite" class="quoted-plain-text">extension Foo: BooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension Bar: DefaultBooType { }</blockquote><blockquote type="cite" class="quoted-plain-text">extension Baz: DefaultBooType { }</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">I'd like to promote the second option as being superior even in</blockquote><blockquote type="cite" class="quoted-plain-text">today's syntax. It is immediately clear to the reader that Foo().boo()</blockquote><blockquote type="cite" class="quoted-plain-text">invokes a different method than Bar().boo(), even if the reader does</blockquote><blockquote type="cite" class="quoted-plain-text">not have access to the original code for structs Foo, Bar, and Baz.</blockquote><blockquote type="cite" class="quoted-plain-text">Suppose those structs were supplied in a third-party library that's</blockquote><blockquote type="cite" class="quoted-plain-text">not well documented. It's plausible that a non-expert coder could try</blockquote><blockquote type="cite" class="quoted-plain-text">to formalize after the fact and write an extension BooType</blockquote><blockquote type="cite" class="quoted-plain-text">implementing boo() unaware that there is an overriding method in Foo.</blockquote><blockquote type="cite" class="quoted-plain-text">In today's Swift syntax, the code would compile and behave subtly</blockquote><blockquote type="cite" class="quoted-plain-text">differently from the author's expectations; as proposed, that code</blockquote><blockquote type="cite" class="quoted-plain-text">would lead to a compile-time error. However, an expert coder who</blockquote><blockquote type="cite" class="quoted-plain-text">intended to supply a default function but invoke any overriding</blockquote><blockquote type="cite" class="quoted-plain-text">methods could write code that is almost as succinct but also</blockquote><blockquote type="cite" class="quoted-plain-text">self-documenting, and in fact could do so today.</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">On Wed, Jan 6, 2016 at 12:45 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text">Am 06.01.2016 um 06:23 schrieb Xiaodi Wu via swift-evolution</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text"><swift-evolution@swift.org>:</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text"><br></blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text">It would remain very much possible to formalize an existing pattern</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text">because, in the case of your example (unless I'm misunderstanding?), you are</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text">not also providing a default implementation of the "min" and "max" getters,</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text">and the IntXX structs would have nothing to override. Indeed, you'd hardly</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text">be formalizing an existing pattern if you had to supply de novo</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><blockquote type="cite" class="quoted-plain-text">implementations!</blockquote></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">The pattern might exist for some existing classes or structs but it might</blockquote><blockquote type="cite" class="quoted-plain-text">still be useful for new classes or even for some existing ones to provide a</blockquote><blockquote type="cite" class="quoted-plain-text">default implementation.</blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text"><br></blockquote><blockquote type="cite" class="quoted-plain-text">-Thorsten</blockquote></span></div></div></blockquote></div></div></body></html>