<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">If you happen not to bump into these issues yet, then simply call yourself lucky. ;)</div> <br> <div id="bloop_sign_1487183405713630976" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div> <br><p class="airmail_on">Am 15. Februar 2017 um 19:27:06, Adrian Zubarev (<a href="mailto:adrian.zubarev@devandartist.com">adrian.zubarev@devandartist.com</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div></div><div>
<title></title>
<div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">
Inline:</div>
<br>
<div id="bloop_sign_1487182636134899968" class="bloop_sign">
<div style="font-family:helvetica,arial;font-size:13px">
-- <br>
Adrian Zubarev<br>
Sent with Airmail</div>
</div>
<br>
<p class="airmail_on">Am 15. Februar 2017 um 19:11:12, Rien
(<a href="mailto:rien@balancingrock.nl">rien@balancingrock.nl</a>)
schrieb:</p>
<div>
<div>
<blockquote type="cite" class="clean_bq" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">
<div>
<div><span><br>
> On 15 Feb 2017, at 18:09, Adrian Zubarev
<adrian.zubarev@devandartist.com> wrote:<span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
> As I already said:<span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
> • To make that feature happen, we need the protocol to be
public (regardless if you can conform to it or not).<span class="Apple-converted-space"> </span><br>
> • Today you can conform to every protocol because in reality
they are open today.<span class="Apple-converted-space"> </span><br>
> • If we remove the property requirement from the protocol the
client can conform it to any type and break my API by calling the
subscript with a wrong type: document["something", NSObject()]
(assuming extension NSObject : SubscriptParameterType).<span class="Apple-converted-space"> </span><br>
> • That forces me to create a requirement for the protocol
which solves the issue in my cases, however there might exist other
issues, which could be far more complicated than mine
is.<span class="Apple-converted-space"> </span><br>
> • That also implies I have make the enum public.<span class="Apple-converted-space"> </span><br>
> • Which follows by the fact that I’m creating unnecessary copy
operations to wrap every instance that conforms to my protocol into
an enum case. From internal API perspective I also have to unwrap
the enum case.<span class="Apple-converted-space"> </span><br>
> Instead if we had consistent public vs. open behavior, I could
make the protocol public (but-not-open), remove the requirement
from it completely, remove the enum completely and simply cast to
Int or String because as the author of the library I would know
that the client won’t be able to conform to my
protocol.<span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
> Importing my library will show the client only
this:<span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
> extension Int : SubscriptParameterType {}<span class="Apple-converted-space"> </span><br>
> extension String : SubscriptParameterType {}<span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
<br>
Ok, thanks, I think I get it now. So you showed the work-around
rather than the problem :-)<span class="Apple-converted-space"> </span><br>
However you could also implement this by creating two subscript
operations, one for integer and one for string.<span class="Apple-converted-space"> </span></span></div>
</div>
</blockquote>
</div>
<p>No not really, the idea behind this approach is carefully
crafted. Plus I do not want optional chaining between subscripts,
this is messy `document[“string”]?[10]?[“key”]`.</p>
<div>
<div>
<blockquote type="cite" class="clean_bq" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">
<div>
<div><span><br>
<br>
So while I agree that this might serve as an example on why a
non-confirmable protocol might be useful, my original question
still stands: how can subclassing create “brittle”
libraries?<span class="Apple-converted-space"> </span></span></div>
</div>
</blockquote>
</div>
<p>If one would want the client user only to use subclasses of a
certain superclass of the same library for whatever reasons. These
subclasses might interact with each other internally (which is not
meant to be public by any means). `final public` will not make it
happen because then you couldn’t create any of these subclasses at
all.</p>
<p>You’re asking here such a general question that simply cannot be
answered easily. I also could ask everyone why on earth would be
want to hide anything from the client? Lets make everything public,
if the client breaks something it’s his fault. <— Clearly not
the way to go right? A distinction between `public` and `open` adds
more flexibility to solve issues that previously might not had any
good solutions.</p>
<div>
<blockquote type="cite" class="clean_bq" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">
<div>
<div><span><br>
<br>
Also note that adding an extra access level did nothing to prevent
brittle libraries… that task is still with the
developer.<span class="Apple-converted-space"> </span><br>
<br>
PS, this is not an educational list, so … :-)<span class="Apple-converted-space"> </span></span></div>
</div>
</blockquote>
</div>
</div>
</div>
<p>Being sarcastic? </p>
<div>
<blockquote type="cite" class="clean_bq" style="font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">
<div>
<div><span><br>
<br>
Regards,<span class="Apple-converted-space"> </span><br>
Rien.<span class="Apple-converted-space"> </span><br>
<br>
><span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
> --<span class="Apple-converted-space"> </span><br>
> Adrian Zubarev<span class="Apple-converted-space"> </span><br>
> Sent with Airmail<span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
> Am 15. Februar 2017 um 17:50:41, Rien (rien@balancingrock.nl)
schrieb:<span class="Apple-converted-space"> </span><br>
><span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
>> > On 15 Feb 2017, at 17:22, Adrian Zubarev via
swift-evolution <swift-evolution@swift.org>
wrote:<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > A short example where I personally wanted a
public-but-not-open protocol:<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > public protocol SubscriptParameterType {<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > // This property was needed to prevent the client
from breaking<span class="Apple-converted-space"> </span><br>
>> > // the library by conforming to the protocol, but I'd
like to<span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > // keep it invisible for the client, or even better
prevent the<span class="Apple-converted-space"> </span><br>
>> > // client from conforming to the
protocol.<span class="Apple-converted-space"> </span><br>
>> > var parameter: Document.SubscriptParameter { get
}<span class="Apple-converted-space"> </span><br>
>> > }<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > extension Document {<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > public enum SubscriptParameter {<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > case string(String)<span class="Apple-converted-space"> </span><br>
>> > case integer(Int)<span class="Apple-converted-space"> </span><br>
>> > }<span class="Apple-converted-space"> </span><br>
>> > }<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > extension String : SubscriptParameterType
{<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > public var parameter: Document.SubscriptParameter
{<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > return .string(self)<span class="Apple-converted-space"> </span><br>
>> > }<span class="Apple-converted-space"> </span><br>
>> > }<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > extension Int : SubscriptParameterType {<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > public var parameter: Document.SubscriptParameter
{<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > return .integer(self)<span class="Apple-converted-space"> </span><br>
>> > }<span class="Apple-converted-space"> </span><br>
>> > }<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > // Somewhere inside the `Document` type<span class="Apple-converted-space"> </span><br>
>> > public subscript(firstKey: String, parameters:
SubscriptParameterType...) -> Value? { … }<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > That implementation enables more safe queries of my
Document type like document["key1", intIndexInstance,
stringKeyInstance, 10, "key"] rather than
document["key1/\(intIndexInstance)/\(stringKeyInstance)/10/key”]<span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
>> I see how that makes queries better.<span class="Apple-converted-space"> </span><br>
>> However what I do not see is how making the protocol
“open” would make this less safe.<span class="Apple-converted-space"> </span><br>
>> (I do not see a reason to make it open either, but that is
not the question)<span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
>> It may be obvious to everyone else, but I don’t see it. Am
I suffering from a brain freeze?.<span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
>> Regards,<span class="Apple-converted-space"> </span><br>
>> Rien.<span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
>> > .<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > --<span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > Adrian Zubarev<span class="Apple-converted-space"> </span><br>
>> > Sent with Airmail<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> > Am 15. Februar 2017 um 17:03:32, Matthew Johnson via
swift-evolution (swift-evolution@swift.org) schrieb:<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>> On Feb 15, 2017, at 9:59 AM, Rien
<Rien@Balancingrock.nl> wrote:<span class="Apple-converted-space"> </span><br>
>> >>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>> On 15 Feb 2017, at 16:45, Matthew Johnson
<matthew@anandabits.com> wrote:<span class="Apple-converted-space"> </span><br>
>> >>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>> On Feb 15, 2017, at 9:35 AM, Rien
<Rien@Balancingrock.nl> wrote:<span class="Apple-converted-space"> </span><br>
>> >>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>> On 15 Feb 2017, at 16:11, Matthew
Johnson via swift-evolution <swift-evolution@swift.org>
wrote:<span class="Apple-converted-space"> </span><br>
>> >>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>> On Feb 15, 2017, at 5:59 AM,
Jeremy Pereira via swift-evolution
<swift-evolution@swift.org> wrote:<span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>>> On 15 Feb 2017, at 11:11,
Brent Royal-Gordon via swift-evolution
<swift-evolution@swift.org> wrote:<span class="Apple-converted-space"> </span><br>
>> >>>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>>> Our philosophy in
general, however, is to default to the behavior which preserves the
most flexibility for the library designer.<span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>> Actually, I thought the
philosophy was to preserver type safety. When did that
change?<span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>> Also, when was the library
designer prioritised ahead of the application
developer?<span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>>> Both open and non-open
classes are common, but we chose to give non-open classes the
`public` keyword because that's the flexibility-preserving
option.<span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>> No it isn’t, it’s the
flexibility restricting option. The consumer of an open class can
subclass it. The consumer of a public class cannot subclass it. How
is the second more flexible than the first?<span class="Apple-converted-space"> </span><br>
>> >>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>> It reduces complexity for the
library author by allowing them to opt-out of the complexity
involved in supporting unknown, user-defined subclasses. It is
important to allow libraries to have this flexibility. They are
free to declare a class `open` if they want to allow subclassing.
It’s even possibly for a library to declare all classes `open` if
it wishes to do so. But *requiring* that would reduce the design
space libraries are allowed to explore and / or introduce fragility
by moving the subclass restriction to a comment.<span class="Apple-converted-space"> </span><br>
>> >>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>> Why would a library author want to
prohibit subclasses?<span class="Apple-converted-space"> </span><br>
>> >>>>> A library user can always wrap the
class and subclass the wrapper.<span class="Apple-converted-space"> </span><br>
>> >>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>> This is composition, not inheritance. The
most important difference is that a wrapper cannot override
methods, it can only wrap and / or forward them. This means that
when the superclass calls a method on `self` that method *always*
invokes its version of that method rather than a subclass override.
This is a very important difference.<span class="Apple-converted-space"> </span><br>
>> >>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>> Agreed, however that does not answer the
question why would a library developer want to disallow
subclassing?<span class="Apple-converted-space"> </span><br>
>> >>> I do not see a use case for that. I.e. a
feature that cannot be implemented without it. (without
“open”)<span class="Apple-converted-space"> </span><br>
>> >><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >> The feature it enables is more robust libraries
and the ability for library authors to better reason about their
code. You may not find this benefit enough to be worth a language
feature, but many of us do.<span class="Apple-converted-space"> </span><br>
>> >><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>> Rien.<span class="Apple-converted-space"> </span><br>
>> >>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>> There are cases where subclassing
does not make sense. And thus preventing subclasses adds
information for those users that don’t RTFM. But that imo is not
worth the impact extra complexity places on all other
users.<span class="Apple-converted-space"> </span><br>
>> >>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>> Rien.<span class="Apple-converted-space"> </span><br>
>> >>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>>
_______________________________________________<span class="Apple-converted-space"> </span><br>
>> >>>>>>> swift-evolution mailing
list<span class="Apple-converted-space"> </span><br>
>> >>>>>>>
swift-evolution@swift.org<span class="Apple-converted-space"> </span><br>
>> >>>>>>>
https://lists.swift.org/mailman/listinfo/swift-evolution<span class="Apple-converted-space"> </span><br>
>> >>>>>><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>>>>>
_______________________________________________<span class="Apple-converted-space"> </span><br>
>> >>>>>> swift-evolution mailing
list<span class="Apple-converted-space"> </span><br>
>> >>>>>>
swift-evolution@swift.org<span class="Apple-converted-space"> </span><br>
>> >>>>>>
https://lists.swift.org/mailman/listinfo/swift-evolution<span class="Apple-converted-space"> </span><br>
>> >><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >>
_______________________________________________<span class="Apple-converted-space"> </span><br>
>> >> swift-evolution mailing list<span class="Apple-converted-space"> </span><br>
>> >> swift-evolution@swift.org<span class="Apple-converted-space"> </span><br>
>> >>
https://lists.swift.org/mailman/listinfo/swift-evolution<span class="Apple-converted-space"> </span><br>
>> ><span class="Apple-converted-space"> </span><span class="Apple-converted-space"> </span><br>
>> >
_______________________________________________<span class="Apple-converted-space"> </span><br>
>> > swift-evolution mailing list<span class="Apple-converted-space"> </span><br>
>> > swift-evolution@swift.org<span class="Apple-converted-space"> </span><br>
>> >
https://lists.swift.org/mailman/listinfo/swift-evolution<span class="Apple-converted-space"> </span><br>
>><span class="Apple-converted-space"> </span><br>
<br></span></div>
</div>
</blockquote>
</div>
</div></div></span></blockquote></body></html>