[Review] SE-0117: Default classes to be non-subclassable publicly

Strong -1 from me.

I think most of my thoughts on this have already been well covered by others. I’ll just note that this proposal reminds me of the fortune file entry, “Whenever you see a sign that says ‘no exit’, it means there is an exit there.”

Specifically, under this proposal, whenever you see a nonsubclassable, non-final class (which I suppose would in fact be any class not explicitly marked as subclassable), it would mean that the library implementor IS in fact subclassing it. Otherwise, it would just be final. Therefore, it’s by definition a perfectly reasonable class to specialize. The implementor just doesn’t want YOU doing it.

Maybe the implementor has a very good reason for this. But in the modal case, probably not. As the ladies on Jerry Springer say: you don’t know me; you don’t know my life. You really have no idea how I’ll be using your API or what I’ll be trying to achieve. In most cases, I'll have both your library source code and intimate knowledge of the application domain, so I’m probably in a better position than you to make these types of architectural assessments. You’re working with nothing but speculation, or even worse, your own myopic perspective of what your library is and how it ought be used. You think you know all about it because it’s Your Damn Library, but so very often, that conception turns out not to be not entirely accurate.

There’s a strong argument for allowing classes to be final, namely, static binding and performance. There’s a strong argument for allowing API to be nonpublic, namely, the ability to be clear about what’s included in the API and what’s not.

Beyond that, I really see no value in being able to schoolmarmishly forbid subclassing and overriding just out of conservatism, regardless of the syntax for this feature or the default behavior. If you want this, go write Ada code.

There should absolutely be a way to say “don’t subclass this.” But do you really need anything more than a comment that says “don’t subclass this?” Perhaps as a compromise, and as a concession to the value of automated checking, this feature could be reformulated as a warning system. A class marked as nonsubclassable could be extended only be including a corresponding acknowledgment keyword in the extending class, a kind of Swift version of -IHaveBeenWarnedThatAPFSIsPreReleaseAndThatIMayLoseData.

Either way, I would be sad to see nonextentability become the default behavior of Swift. That just doesn’t seem like it’s in anyone’s best interest.

Garth

Personally I think a great compromise is just forcing the user to use the
`override` keyword when subclassing in these cases. That way the library
maker can mark classes that aren't supported or are internal and ideally
shouldn't be used by the programmer.

However we shouldn't baby sit programmers, we are smart people after all.
So if there is a huge catastrophic bug that just happens to be easily
solvable by subclassing or whatever then we should allow them to do so.

An `override` keyword would be a great compromise, take this class:

public class NonSubclassableParentClass {

}

If the programmer subclasses it normally, the compiler will throw an error
telling them to use the `override` keyword to subclass non-subclassble
classes:

override class MySubclass: NonSubclassableParentClass {

}

Now there is a clear indicator that we are doing something not safe or
ideal here. This is similar how the "!" in IUO indicates we have a unsafe
value. We are grown-ups we should be able to know when to subclass but this
doesn't mean there couldn't be something like this to indicate to the user
that they may want to revaluate this in the future.

So in the future other programmers can see this marker and think "Oh we are
using this class in a non recommended way, so when it breaks when I upgrade
the library it's our fault." hopefully making them continue to upgrade
rather than not upgrading because it breaks "my subclass".

Whats great about this feature is it also allows linters or the compiler to
also show warnings when this is used as well, that way those of us that are
bugged by the amount of warnings we have in our app can endevour to fix it.

In Ruby there is a convention to have these sort of monkey patches and
subclasses to fix bugs in a special folder with "_ext" after it to indicate
that this an extension to a class from a library, this indicates to the
programmer that it's something we should ideally remove as soon as the app
can work without that hack.

So I can't see why we can't have this `override` keyword to tell the
library developer that we like to live life on the edge a litte ;)

···

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 8 July 2016 at 22:14, Tino Heth via swift-evolution < swift-evolution@swift.org> wrote:

When was the last time you you thought "I really wish the author of that
library had restricted my options to use it"?

I really wish Objective-C had this feature from the start. I believe
there would have been significant benefits to Apple's platforms and
ecosystem. The reasons for believing (or not believing) this have been
discussed in depth so there isn't a need to rehash them now.

I'm not asking for reasons but for a single persuasive example…

It is easy to claim that everything will be better if we add restrictions,
but so far, I haven't heard of any real problems cause by the current
defaults:
The motivation to change them is not because of actual experience, it's
just the trendy opinion that inheritance is evil.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Two days ago, I challenged the supporters of this proposal to show a singe persuasive example to illustrate that this proposal could actually improve something.
I got a single reply — which did not contain an example, but just the claim that there is one…
Imho that alone should be enough to cancel the whole thing, because even if there are cases which cannot be repelled with the simple advice "just don't subclass", this would only be a basis to start talking about the actual pros and cons.

So for me, the promised benefits are less likely than the existence of Bigfoot:
I guess there are at least several hundred people who swore they have seen him, and there are even some blurry photos ;-)

Of course, it is impossible to come up with an unquestionable argument for the change — and it's also impossible to prove the opposite, because the whole debate makes as much sense as arguing wether raisins are tasteful or terrible; it's nothing but personal preference, and the only thing we can hope for is that the bias of those who will decide this proposal isn't at odds with the needs of the majority.

If we can agree that it is not about facts, but about opinion, there are still fundamental arguments against SE-0117:
Those who have issues with subclassing can just resign from it (as users of a library), and they can annotate their classes to dictate their usage (as an author) — but if you think subclassing is still a good tool, you can't do anything with a sealed class.
Additionally, please note that those who ask for stricter rules and more regulation have many reasons to be happy with the status quo:
You can subclass neither structs nor enums, and by default, you can't inherit from a framework-class as well, because it is internal — and yet they yell for more.

Swift claims to be opinionated, not to aim for compromise — but if plain old OO isn't compatible with the ideals of the language, it would be more honest to just completely remove inheritance instead of slowly crippling it's possibilities.

- Tino

Tino Heth wrote: ...I challenged [supporters] to show a singe persuasive example to illustrate that this proposal could actually improve something...even if there are cases which cannot be repelled with the simple advice "just don't subclass", this would only be a basis to start talking about the actual pros and cons.

Leonardo Pessoa responded: ...an app which will have object representations of Files and Folders (both come from a common class called Entry). You [can] extend from File and Entry freely but...it is important you don't subclass any type of Folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

To me, this scenario seems like an example of why the proposal should be rejected.

Correct me if I’m wrong, but your (Leonardo’s) narrative suggests that the subclassability of File and Entry is incidental. If the intent was actively to allow people to provide their own implementations of filesystem objects, you would presumably have taken whatever steps were necessary to make Folder subclassable as well.

This scenario ends up defining a perfectly commonplace mix of classes. Some of them behave reasonably when subclassed and some don’t. The question is, should Swift — as a matter of default policy and community style — actively push you to seal ALL of these classes?

No, it shouldn’t. You’d be removing the possibility of functionality that’s potentially useful to some clients, without gaining much in return.

A “sealed” keyword or equivalent seems plausible, but it shouldn’t be the default.

Even an affirmative “sealed" feels prone to abuse, however. In this case, for example, I would imagine there would be considerable temptation to mark all objects (Entry, File, Folder, etc.) as sealed, just because Folder needs it. API designers (and clients!) dislike unexplained asymmetry.

Garth

Should I assume then you want so much this proposal to be dropped you didn't even mind to look for the example so you wouldn't have to admit this proposal is needed? Fine, here is the whole of that example.

I'm currently working on an app which will have object representations of Files and Folders (both come from a common class called Entry). You as a developer for this system will be entitled to extend from File and Entry freely but you can only work with Folders and its subclasses (specialised folders) but to this system it is important you don't subclass any type of folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

There may be several more examples but this is one I'm facing right now, so I can assure you it is a true example. IMO libraries are to be written with intention in mind and I don't think it is right to use a library written to compose a PDF file to send an email (even if you're sending the PDF file attached, the right way to do it is by composition not subclassing).

Additionally, someone mentioned and I went in to check about a recommendation for Java to intentionally document and enable classes to be subclasses explicitly otherwise forbid it at all and that recommendation seems to come from Oracle itself. I believe Oracle would do it to Java if it had great interest in it without consulting anyone's opinion.

About the addition to the proposal to enable force unsealing, I'm completely opposed as it is just like not having any of this protection at all (why putting a lock on the door to your house if the key is under the mat?)

Swift doesn't have to follow on the footsteps of any language but what is best for the intention the language was created for. If sealed by default goes in that direction, then we should have it not looking back. The same goes if we decide this is not taking the language in its intended direction. If I'm not wrong at least one member of the core team already mentioned in this thread this is completely aligned with the intention of the language, so I think we should give it a go and stop trying to have/keep control of everything we touch.

L

···

-----Original Message-----
From: "Tino Heth via swift-evolution" <swift-evolution@swift.org>
Sent: ‎10/‎07/‎2016 01:55 PM
To: "swift-evolution" <swift-evolution@swift.org>
Cc: "Jean-Daniel Dupas" <mailing@xenonium.com>
Subject: Re: [swift-evolution] [Review] SE-0117: Default classes to benon-subclassable publicly

Two days ago, I challenged the supporters of this proposal to show a singe persuasive example to illustrate that this proposal could actually improve something.
I got a single reply — which did not contain an example, but just the claim that there is one…
Imho that alone should be enough to cancel the whole thing, because even if there are cases which cannot be repelled with the simple advice "just don't subclass", this would only be a basis to start talking about the actual pros and cons.

So for me, the promised benefits are less likely than the existence of Bigfoot:
I guess there are at least several hundred people who swore they have seen him, and there are even some blurry photos ;-)

Of course, it is impossible to come up with an unquestionable argument for the change — and it's also impossible to prove the opposite, because the whole debate makes as much sense as arguing wether raisins are tasteful or terrible; it's nothing but personal preference, and the only thing we can hope for is that the bias of those who will decide this proposal isn't at odds with the needs of the majority.

If we can agree that it is not about facts, but about opinion, there are still fundamental arguments against SE-0117:
Those who have issues with subclassing can just resign from it (as users of a library), and they can annotate their classes to dictate their usage (as an author) — but if you think subclassing is still a good tool, you can't do anything with a sealed class.
Additionally, please note that those who ask for stricter rules and more regulation have many reasons to be happy with the status quo:
You can subclass neither structs nor enums, and by default, you can't inherit from a framework-class as well, because it is internal — and yet they yell for more.

Swift claims to be opinionated, not to aim for compromise — but if plain old OO isn't compatible with the ideals of the language, it would be more honest to just completely remove inheritance instead of slowly crippling it's possibilities.

- Tino
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

You asked me to correct you and I shall: you're wrong. Although it seems like a filesystem representation here, this is not it and the subclassability of Entry and File is intended but Folder is a special type and I cannot allow more than the base type and a few controlled subclasses due to the nature of the system. It was intended to be exactly like this and there was nothing incidental about them. IMO a well designed library is like an app with plugins: you're not entitled to do whatever you want in the app through a plugin but the app controls and dictates what it allows you to do.

You asked for an example where this feature would be needed and I've provided. As I said, a concrete and real example. But I haven't seen anyone give the slightest concrete technical reason not to approve it and please don't come saying fix bugs in a library by subclassing because that's not what subclassing is for. That is a misuse of object orientation in whichever language you're working with.

L

···

-----Original Message-----
From: "Garth Snyder via swift-evolution" <swift-evolution@swift.org>
Sent: ‎10/‎07/‎2016 05:47 PM
To: "swift-evolution" <swift-evolution@swift.org>
Subject: Re: [swift-evolution] [Review] SE-0117: Default classes to benon-subclassable publicly

Tino Heth wrote: ...I challenged [supporters] to show a singe persuasive example to illustrate that this proposal could actually improve something...even if there are cases which cannot be repelled with the simple advice "just don't subclass", this would only be a basis to start talking about the actual pros and cons.

Leonardo Pessoa responded: ...an app which will have object representations of Files and Folders (both come from a common class called Entry). You [can] extend from File and Entry freely but...it is important you don't subclass any type of Folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

To me, this scenario seems like an example of why the proposal should be rejected.

Correct me if I’m wrong, but your (Leonardo’s) narrative suggests that the subclassability of File and Entry is incidental. If the intent was actively to allow people to provide their own implementations of filesystem objects, you would presumably have taken whatever steps were necessary to make Folder subclassable as well.

This scenario ends up defining a perfectly commonplace mix of classes. Some of them behave reasonably when subclassed and some don’t. The question is, should Swift — as a matter of default policy and community style — actively push you to seal ALL of these classes?

No, it shouldn’t. You’d be removing the possibility of functionality that’s potentially useful to some clients, without gaining much in return.

A “sealed” keyword or equivalent seems plausible, but it shouldn’t be the default.

Even an affirmative “sealed" feels prone to abuse, however. In this case, for example, I would imagine there would be considerable temptation to mark all objects (Entry, File, Folder, etc.) as sealed, just because Folder needs it. API designers (and clients!) dislike unexplained asymmetry.

Garth

Should I assume then you want so much this proposal to be dropped you didn't even mind to look for the example so you wouldn't have to admit this proposal is needed? Fine, here is the whole of that example.

This list has thousands of messages, this topic alone is split into at least six threads… I tried, but how much time should I spend searching without any helpful hint?
But let's see what we got now...

I'm currently working on an app

wait a minute: An app, not a library? What difference will sealed make here at all?

which will have object representations of Files and Folders (both come from a common class called Entry). You as a developer for this system will be entitled to extend from File and Entry freely but you can only work with Folders and its subclasses (specialised folders) but to this system it is important you don't subclass any type of folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

So, how many types of directories may exist that you would have to mark as final? (serious question — please don't ignore it)
I don't know about you specific model, but for me, invisible directories and bundles would be all I'd be worried about — and those are basically all normal folders as well…
So, do those subclasses each have special properties? There is only a limited set of metadata a directory can have, so I expect there is no need for subclassing at all: Is there a special reason why it can't be a single class, or an enum?
This may all be useless advice that doesn't work for your case — but if I stick with the Sasquatch-metapher, this is a very blurred picture...

IMO libraries are to be written with intention in mind and I don't think it is right to use a library written to compose a PDF file to send an email (even if you're sending the PDF file attached, the right way to do it is by composition not subclassing).

How is this statement connected to the proposal?
The only way to prevent misuse of software is not to write it; and what harm is done to you as the author of a PDF-lib (btw: been there, done that — nasty format ;-) if some stupid user turns your composer into Emacs?

Additionally, someone mentioned and I went in to check about a recommendation for Java to intentionally document and enable classes to be subclasses explicitly otherwise forbid it at all and that recommendation seems to come from Oracle itself. I believe Oracle would do it to Java if it had great interest in it without consulting anyone's opinion.

good point… Oracle is widely known for its instinctive knowledge about the needs and problems of their customers — which they than tend to ignore and do something different ;-)

About the addition to the proposal to enable force unsealing, I'm completely opposed as it is just like not having any of this protection at all (why putting a lock on the door to your house if the key is under the mat?)

As long as we don't speak about commercial libraries, which are a curiosity in the Swift-cosmos:
There is no lock, there is not even a door — there is only a tiny sign that says "please don't enter", and the worst thing that could happen if you ignore it is that the original owner stops doing the housework.

If I'm not wrong at least one member of the core team already mentioned in this thread this is completely aligned with the intention of the language, so I think we should give it a go and stop trying to have/keep control of everything we touch.

Isn't this exactly what this proposal is about? Replacing freedom with control? Stop trying to keep control of everything is actually a good idea in the light of this proposal.

I appreciate that you described your case, but it didn't do anything to convince me.

Tino

Leonardo's example makes the case for why Swift should adopt a 'sealed'
keyword that can be used to make public classes non-subclassable outside
the module where they are defined, but not for why this should be the
default.

Others have made these points before, but these are the two biggest reasons
I can see against making public classes non-subclassable by default:

1. It is the opposite of nearly every other OOP language's behavior and the
opposite of what anyone will expect who is coming to Swift after doing any
OOP programming anywhere else. While I believe that Swift should be free to
buck the trends of other languages where there are significant advantages,
changing something this fundamental will introduce a new learning curve for
even experienced programmers. The advantages better be significant,
otherwise you are introducing a frustrating quirk into the language without
any great benefit in exchange. But the advantages of default
non-subclassability are marginal at best. Whatever advantage there is can
be achieved by making it opt-in using a 'sealed' keywrod, instead of by
making it the default.

2. The motivation seems to be that it will force better API design. On
average, I can't believe that it will. Assume that there are two kinds of
developers: Those that make careful decisions about their API design and
those that don't. The ones that make careful decisions about their API
design will continue to do so - I don't see any significant improvement to
their code by making non-subclassability the default. The developers who
don't make careful design decisions will just go with the default - in this
case they will just leave the default in place, and their public classes
will not be subclassable. That doesn't improve anything, it just makes
sloppy, poorly written code harder to fix in the off-chance that you are
stuck working with it. In other words, quality will not improve, but
productivity will suffer, because it will be harder to develop workarounds
for the problems that will inevitably appear in even the best-designed APIs.

3. It is a bad interpretation of the stated goal that Swift should help
developers produce "safe code." Some folks seem to believe that this means
that the language should protect people from themselves. If I am using your
API in my code and I screw it up by subclassing something that I shouldn't
have, that is somehow a language defect. It is not a language defect - it
is me being an idiot. Don't spend a lot of time trying to make a language
idiot-proof - idiots are geniuses and you will never outsmart them.
Personally, when I read that Swift helps produce "safe code", what that
means primarily is that it has a type system that helps reveal the vast
majority of bugs that would otherwise go unnoticed until runtime. In other
words, safety is related to discovering hidden flaws in the program. (Type
safety isn't the only feature that helps with this, but it is perhaps the
main one.) But this whole issue of default non-subclassability doesn't fall
into that category of "safety" at all. It doesn't help a programmer produce
safer code. The same hidden flaws will persist whether non-subclassability
is the default or not. The difference is that those same hidden flaws will
be more difficult to deal with after the fact.

To sum it up, +1 for introducing a 'sealed' keyword, but -1 for making it
the default behavior for public classes.

···

On Sun, Jul 10, 2016 at 12:18 PM Leonardo Pessoa via swift-evolution < swift-evolution@swift.org> wrote:

Should I assume then you want so much this proposal to be dropped you
didn't even mind to look for the example so you wouldn't have to admit this
proposal is needed? Fine, here is the whole of that example.

I'm currently working on an app which will have object representations of
Files and Folders (both come from a common class called Entry). You as a
developer for this system will be entitled to extend from File and Entry
freely but you can only work with Folders and its subclasses (specialised
folders) but to this system it is important you don't subclass any type of
folder. Without this proposal I would have to create workarounds to prevent
you from doing that while still allowing me to subclass while playing a lot
of finals everywhere. And so far I would have to allow you to subclass
Folder itself (at least) but you would complain (and possibly file a bug
report to me) because it would not be working properly because your classes
would not benefit from the workaround. In this case, if I could subclass
internally but prevent you from doing it, you could complain I'm not
allowing you to do whatever you want but you wouldn't complain my code
doesn't work properly (it does, you just won't know it).

There may be several more examples but this is one I'm facing right now,
so I can assure you it is a true example. IMO libraries are to be written
with intention in mind and I don't think it is right to use a library
written to compose a PDF file to send an email (even if you're sending the
PDF file attached, the right way to do it is by composition not
subclassing).

Additionally, someone mentioned and I went in to check about a
recommendation for Java to intentionally document and enable classes to be
subclasses explicitly otherwise forbid it at all and that recommendation
seems to come from Oracle itself. I believe Oracle would do it to Java if
it had great interest in it without consulting anyone's opinion.

About the addition to the proposal to enable force unsealing, I'm
completely opposed as it is just like not having any of this protection at
all (why putting a lock on the door to your house if the key is under the
mat?)

Swift doesn't have to follow on the footsteps of any language but what is
best for the intention the language was created for. If sealed by default
goes in that direction, then we should have it not looking back. The same
goes if we decide this is not taking the language in its intended
direction. If I'm not wrong at least one member of the core team already
mentioned in this thread this is completely aligned with the intention of
the language, so I think we should give it a go and stop trying to
have/keep control of everything we touch.

L
------------------------------
From: Tino Heth via swift-evolution <swift-evolution@swift.org>
Sent: ‎10/‎07/‎2016 01:55 PM
To: swift-evolution <swift-evolution@swift.org>
Cc: Jean-Daniel Dupas <mailing@xenonium.com>
Subject: Re: [swift-evolution] [Review] SE-0117: Default classes to
benon-subclassable publicly

Two days ago, I challenged the supporters of this proposal to show a singe
persuasive example to illustrate that this proposal could actually improve
something.
I got a single reply — which did not contain an example, but just the
claim that there is one…
Imho that alone should be enough to cancel the whole thing, because even
if there are cases which cannot be repelled with the simple advice "just
don't subclass", this would only be a basis to start talking about the
actual pros and cons.

So for me, the promised benefits are less likely than the existence of
Bigfoot:
I guess there are at least several hundred people who swore they have seen
him, and there are even some blurry photos ;-)

Of course, it is impossible to come up with an unquestionable argument for
the change — and it's also impossible to prove the opposite, because the
whole debate makes as much sense as arguing wether raisins are tasteful or
terrible; it's nothing but personal preference, and the only thing we can
hope for is that the bias of those who will decide this proposal isn't at
odds with the needs of the majority.

If we can agree that it is not about facts, but about opinion, there are
still fundamental arguments against SE-0117:
Those who have issues with subclassing can just resign from it (as users
of a library), and they can annotate their classes to dictate their usage
(as an author) — but if you think subclassing is still a good tool, you
can't do anything with a sealed class.
Additionally, please note that those who ask for stricter rules and more
regulation have many reasons to be happy with the status quo:
You can subclass neither structs nor enums, and by default, you can't
inherit from a framework-class as well, because it is internal — and yet
they yell for more.

Swift claims to be opinionated, not to aim for compromise — but if plain
old OO isn't compatible with the ideals of the language, it would be more
honest to just completely remove inheritance instead of slowly crippling
it's possibilities.

- Tino
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Interesting example but it only explain that a sealed keyword is needed (which I agree), and not why sealed should be the default (which I disagree).

···

Le 10 juil. 2016 à 21:18, Leonardo Pessoa <me@lmpessoa.com> a écrit :

Should I assume then you want so much this proposal to be dropped you didn't even mind to look for the example so you wouldn't have to admit this proposal is needed? Fine, here is the whole of that example.

I'm currently working on an app which will have object representations of Files and Folders (both come from a common class called Entry). You as a developer for this system will be entitled to extend from File and Entry freely but you can only work with Folders and its subclasses (specialised folders) but to this system it is important you don't subclass any type of folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

There may be several more examples but this is one I'm facing right now, so I can assure you it is a true example. IMO libraries are to be written with intention in mind and I don't think it is right to use a library written to compose a PDF file to send an email (even if you're sending the PDF file attached, the right way to do it is by composition not subclassing).

Additionally, someone mentioned and I went in to check about a recommendation for Java to intentionally document and enable classes to be subclasses explicitly otherwise forbid it at all and that recommendation seems to come from Oracle itself. I believe Oracle would do it to Java if it had great interest in it without consulting anyone's opinion.

About the addition to the proposal to enable force unsealing, I'm completely opposed as it is just like not having any of this protection at all (why putting a lock on the door to your house if the key is under the mat?)

Swift doesn't have to follow on the footsteps of any language but what is best for the intention the language was created for. If sealed by default goes in that direction, then we should have it not looking back. The same goes if we decide this is not taking the language in its intended direction. If I'm not wrong at least one member of the core team already mentioned in this thread this is completely aligned with the intention of the language, so I think we should give it a go and stop trying to have/keep control of everything we touch.

L
From: Tino Heth via swift-evolution <mailto:swift-evolution@swift.org>
Sent: ‎10/‎07/‎2016 01:55 PM
To: swift-evolution <mailto:swift-evolution@swift.org>
Cc: Jean-Daniel Dupas <mailto:mailing@xenonium.com>
Subject: Re: [swift-evolution] [Review] SE-0117: Default classes to benon-subclassable publicly

Two days ago, I challenged the supporters of this proposal to show a singe persuasive example to illustrate that this proposal could actually improve something.
I got a single reply — which did not contain an example, but just the claim that there is one…
Imho that alone should be enough to cancel the whole thing, because even if there are cases which cannot be repelled with the simple advice "just don't subclass", this would only be a basis to start talking about the actual pros and cons.

So for me, the promised benefits are less likely than the existence of Bigfoot:
I guess there are at least several hundred people who swore they have seen him, and there are even some blurry photos ;-)

Of course, it is impossible to come up with an unquestionable argument for the change — and it's also impossible to prove the opposite, because the whole debate makes as much sense as arguing wether raisins are tasteful or terrible; it's nothing but personal preference, and the only thing we can hope for is that the bias of those who will decide this proposal isn't at odds with the needs of the majority.

If we can agree that it is not about facts, but about opinion, there are still fundamental arguments against SE-0117:
Those who have issues with subclassing can just resign from it (as users of a library), and they can annotate their classes to dictate their usage (as an author) — but if you think subclassing is still a good tool, you can't do anything with a sealed class.
Additionally, please note that those who ask for stricter rules and more regulation have many reasons to be happy with the status quo:
You can subclass neither structs nor enums, and by default, you can't inherit from a framework-class as well, because it is internal — and yet they yell for more.

Swift claims to be opinionated, not to aim for compromise — but if plain old OO isn't compatible with the ideals of the language, it would be more honest to just completely remove inheritance instead of slowly crippling it's possibilities.

- Tino
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Yes, app. Apps can be extended through plugins and you cannot write a plugin to an app without a library that exposes what you can do. That alone can expand my simple sample into a variety of examples: plugins.

For the many types of folders I cannot enter details of my app now but check macOS' folders: aside the basics you have smart folders, disks, remote folders and so forth. They follow the same basics but some specificities will vary. You can create as many different files you want but can you create a new type of folder there? Same here.

Too bad my example did not convince you but subclassing to fix bugs also don't convince me. I really believed this is the behaviour that leads bugs in a library not to be fixed: because instead of helping improving the library for everyone you fix it for yourself and let it go. The developer of the library doesn't even care to fix the bug since everyone uses your subclass fix or he finds out purple doing this, fixes the bug and puts a final there breaking everyone's app.

L

···

-----Original Message-----
From: "Tino Heth" <2th@gmx.de>
Sent: ‎10/‎07/‎2016 05:47 PM
To: "Leonardo Pessoa" <me@lmpessoa.com>
Cc: "swift-evolution" <swift-evolution@swift.org>; "Jean-Daniel Dupas" <mailing@xenonium.com>
Subject: Re: [swift-evolution] [Review] SE-0117: Default classes tobenon-subclassable publicly

Should I assume then you want so much this proposal to be dropped you didn't even mind to look for the example so you wouldn't have to admit this proposal is needed? Fine, here is the whole of that example.

This list has thousands of messages, this topic alone is split into at least six threads… I tried, but how much time should I spend searching without any helpful hint?
But let's see what we got now...

I'm currently working on an app
wait a minute: An app, not a library? What difference will sealed make here at all?

which will have object representations of Files and Folders (both come from a common class called Entry). You as a developer for this system will be entitled to extend from File and Entry freely but you can only work with Folders and its subclasses (specialised folders) but to this system it is important you don't subclass any type of folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

So, how many types of directories may exist that you would have to mark as final? (serious question — please don't ignore it)
I don't know about you specific model, but for me, invisible directories and bundles would be all I'd be worried about — and those are basically all normal folders as well…
So, do those subclasses each have special properties? There is only a limited set of metadata a directory can have, so I expect there is no need for subclassing at all: Is there a special reason why it can't be a single class, or an enum?
This may all be useless advice that doesn't work for your case — but if I stick with the Sasquatch-metapher, this is a very blurred picture...

IMO libraries are to be written with intention in mind and I don't think it is right to use a library written to compose a PDF file to send an email (even if you're sending the PDF file attached, the right way to do it is by composition not subclassing).

How is this statement connected to the proposal?
The only way to prevent misuse of software is not to write it; and what harm is done to you as the author of a PDF-lib (btw: been there, done that — nasty format ;-) if some stupid user turns your composer into Emacs?

Additionally, someone mentioned and I went in to check about a recommendation for Java to intentionally document and enable classes to be subclasses explicitly otherwise forbid it at all and that recommendation seems to come from Oracle itself. I believe Oracle would do it to Java if it had great interest in it without consulting anyone's opinion.

good point… Oracle is widely known for its instinctive knowledge about the needs and problems of their customers — which they than tend to ignore and do something different ;-)

About the addition to the proposal to enable force unsealing, I'm completely opposed as it is just like not having any of this protection at all (why putting a lock on the door to your house if the key is under the mat?)

As long as we don't speak about commercial libraries, which are a curiosity in the Swift-cosmos:
There is no lock, there is not even a door — there is only a tiny sign that says "please don't enter", and the worst thing that could happen if you ignore it is that the original owner stops doing the housework.

If I'm not wrong at least one member of the core team already mentioned in this thread this is completely aligned with the intention of the language, so I think we should give it a go and stop trying to have/keep control of everything we touch.

Isn't this exactly what this proposal is about? Replacing freedom with control? Stop trying to keep control of everything is actually a good idea in the light of this proposal.

I appreciate that you described your case, but it didn't do anything to convince me.

Tino

No, that wasn’t my motivation in giving it a +1. This seems to be a common misunderstanding in the “no” camp, so I’ll address it.

Accepting this proposal won’t turn bad API designers into good ones. Crappy APIs are still going to be crappy with or without this. In the immortal quote apparently due to Lawrence Flon: “There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code.”

The justification for this proposal is all about supporting the people who are working to design library APIs right, and about maintaining consistency with the design philosophy of Swift. To wit: in Swift, where there’s a default choice, it’s the safe one; where there’s a consequential design decision, it’s explicit.

Rod Brown hit the crux of it: sealed → open is safe for existing API clients, but open → sealed is a breaking change. “Sealed” is thus the safer choice, and “open” is a consequential design decision. Given the general precedent and philosophy of Swift, competent API designers might reasonably be taken aback that open is the default. In fact, given the habit Swift encourages of leaning on compiler verification, this is a potential source of designer error.

• • •

For those who think that discouraging inheritance by default is something recent, or a fad, or a quirk of Swift: Josh Bloch spent over 5 pages of Effective Java arguing against “subclassable just in case.” That was in 2001, and it was old news even back then.

Those looking for a more detailed analysis of the problems caused by APIs allowing inheritance without designing for it should read his analysis. It’s 15 years old, it’s Java, but it still stands. (He even gives instructions toward the end for simulating something very much like the here-proposed “sealed” in Java using package-private initializers.) It’s item 15 in the book, “Design and document for inheritance or else prohibit it.”

Cheers,

Paul

···

On Jul 10, 2016, at 8:49 PM, let var go via swift-evolution <swift-evolution@swift.org> wrote:

2. The motivation seems to be that it will force better API design.

2. The motivation seems to be that it will force better API design.

No, that wasn’t my motivation in giving it a +1. This seems to be a common misunderstanding in the “no” camp, so I’ll address it.

Accepting this proposal won’t turn bad API designers into good ones. Crappy APIs are still going to be crappy with or without this. In the immortal quote apparently due to Lawrence Flon: “There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code.”

The justification for this proposal is all about supporting the people who are working to design library APIs right, and about maintaining consistency with the design philosophy of Swift. To wit: in Swift, where there’s a default choice, it’s the safe one; where there’s a consequential design decision, it’s explicit.

+1. This is exactly why sealed is the default that fits best with the rest of the defaults in Swift. They are permissive within a module and require explicit choices where external contracts are involved.

Rod Brown hit the crux of it: sealed → open is safe for existing API clients, but open → sealed is a breaking change. “Sealed” is thus the safer choice, and “open” is a consequential design decision. Given the general precedent and philosophy of Swift, competent API designers might reasonably be taken aback that open is the default. In fact, given the habit Swift encourages of leaning on compiler verification, this is a potential source of designer error.

• • •

For those who think that discouraging inheritance by default is something recent, or a fad, or a quirk of Swift: Josh Bloch spent over 5 pages of Effective Java arguing against “subclassable just in case.” That was in 2001, and it was old news even back then.

Those looking for a more detailed analysis of the problems caused by APIs allowing inheritance without designing for it should read his analysis. It’s 15 years old, it’s Java, but it still stands. (He even gives instructions toward the end for simulating something very much like the here-proposed “sealed” in Java using package-private initializers.) It’s item 15 in the book, “Design and document for inheritance or else prohibit it.”

Agree. The best practice has been around for some time, although it sounds like it is not yet widespread as it could be (especially in-depth knowledge of the rationale behind it).

What is relatively new is the opportunity to embrace it in the design of a (sure to be) popular and widely used language that carries most of the traditional OO facilities. This is a great opportunity IMO.

···

On Jul 10, 2016, at 9:53 PM, Paul Cantrell via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 10, 2016, at 8:49 PM, let var go via swift-evolution <swift-evolution@swift.org> wrote:

Cheers,

Paul

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

To share some perspective, I come from working on 200k to 500k LOC systems, with the largest (aside linux kernel drivers) being ~2M loc/20,000 cpp files. I have done my share of objc coding, much of it for my own usage. My interest in swift has to do with finding a scalable solution for client server systems where code would be shared between the two sides. Currently I do that with c# and started experimenting with phonegap&node using typescript (I share Anders Hejlsberg's view that past a few 1000 locs javascript becomes readonly).
If I can appreciate that as an app-only language a number of tradeoffs are not terribly important in the long run, I question whether the same choices are equally inconsequential at the other end of the scale. I took seriously that apple will let swift become credible on the server side, but it might require that this community remembers to consider both ends of the scale when helping shape this language. I have read a lot past discussions of the last month, and I do wonder where people see this language go, and more importantly where they want to see it go. I do hope the future of swift is not just made of apps.
Regards
(From mobile)

···

On Jul 10, 2016, at 10:47 PM, Tino Heth via swift-evolution <swift-evolution@swift.org> wrote:

Should I assume then you want so much this proposal to be dropped you didn't even mind to look for the example so you wouldn't have to admit this proposal is needed? Fine, here is the whole of that example.

This list has thousands of messages, this topic alone is split into at least six threads… I tried, but how much time should I spend searching without any helpful hint?
But let's see what we got now...

I'm currently working on an app

wait a minute: An app, not a library? What difference will sealed make here at all?

which will have object representations of Files and Folders (both come from a common class called Entry). You as a developer for this system will be entitled to extend from File and Entry freely but you can only work with Folders and its subclasses (specialised folders) but to this system it is important you don't subclass any type of folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

So, how many types of directories may exist that you would have to mark as final? (serious question — please don't ignore it)
I don't know about you specific model, but for me, invisible directories and bundles would be all I'd be worried about — and those are basically all normal folders as well…
So, do those subclasses each have special properties? There is only a limited set of metadata a directory can have, so I expect there is no need for subclassing at all: Is there a special reason why it can't be a single class, or an enum?
This may all be useless advice that doesn't work for your case — but if I stick with the Sasquatch-metapher, this is a very blurred picture...

IMO libraries are to be written with intention in mind and I don't think it is right to use a library written to compose a PDF file to send an email (even if you're sending the PDF file attached, the right way to do it is by composition not subclassing).

How is this statement connected to the proposal?
The only way to prevent misuse of software is not to write it; and what harm is done to you as the author of a PDF-lib (btw: been there, done that — nasty format ;-) if some stupid user turns your composer into Emacs?

Additionally, someone mentioned and I went in to check about a recommendation for Java to intentionally document and enable classes to be subclasses explicitly otherwise forbid it at all and that recommendation seems to come from Oracle itself. I believe Oracle would do it to Java if it had great interest in it without consulting anyone's opinion.

good point… Oracle is widely known for its instinctive knowledge about the needs and problems of their customers — which they than tend to ignore and do something different ;-)

About the addition to the proposal to enable force unsealing, I'm completely opposed as it is just like not having any of this protection at all (why putting a lock on the door to your house if the key is under the mat?)

As long as we don't speak about commercial libraries, which are a curiosity in the Swift-cosmos:
There is no lock, there is not even a door — there is only a tiny sign that says "please don't enter", and the worst thing that could happen if you ignore it is that the original owner stops doing the housework.

If I'm not wrong at least one member of the core team already mentioned in this thread this is completely aligned with the intention of the language, so I think we should give it a go and stop trying to have/keep control of everything we touch.

Isn't this exactly what this proposal is about? Replacing freedom with control? Stop trying to keep control of everything is actually a good idea in the light of this proposal.

I appreciate that you described your case, but it didn't do anything to convince me.

Tino

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

IMHO SE-0117 is one of the worst Swift 3 proposals that have ever been proposed. It has the potential to make the language much worse. I haven't seen any problems at all that are caused by people trying to subclass classes that they shouldn't, so I'm wondering where this fear of bad subclass behavior comes from. And for the performance argument: there is no performance benefit of this proposal. I cannot prove this of course, but you'll remember my words in a year or so, when this proposal has been adopted and we can measure the alleged benefits of it. I can already see how this "feature" will be rolled back for Swift 4 ;)

I'm not against change in general. I think going from Swift 1 to Swift 2 was a big improvement. Swift 2 to Swift 3 is overall okay, but it gets worse by introducing things like NoReturn/Never or sealed subclasses.

-Michael

···

Am 11.07.2016 um 00:53 schrieb Leonardo Pessoa via swift-evolution <swift-evolution@swift.org>:

Yes, app. Apps can be extended through plugins and you cannot write a plugin to an app without a library that exposes what you can do. That alone can expand my simple sample into a variety of examples: plugins.

For the many types of folders I cannot enter details of my app now but check macOS' folders: aside the basics you have smart folders, disks, remote folders and so forth. They follow the same basics but some specificities will vary. You can create as many different files you want but can you create a new type of folder there? Same here.

Too bad my example did not convince you but subclassing to fix bugs also don't convince me. I really believed this is the behaviour that leads bugs in a library not to be fixed: because instead of helping improving the library for everyone you fix it for yourself and let it go. The developer of the library doesn't even care to fix the bug since everyone uses your subclass fix or he finds out purple doing this, fixes the bug and puts a final there breaking everyone's app.

L
From: Tino Heth
Sent: ‎10/‎07/‎2016 05:47 PM
To: Leonardo Pessoa
Cc: swift-evolution; Jean-Daniel Dupas
Subject: Re: [swift-evolution] [Review] SE-0117: Default classes tobenon-subclassable publicly

Should I assume then you want so much this proposal to be dropped you didn't even mind to look for the example so you wouldn't have to admit this proposal is needed? Fine, here is the whole of that example.

This list has thousands of messages, this topic alone is split into at least six threads… I tried, but how much time should I spend searching without any helpful hint?
But let's see what we got now...

I'm currently working on an app

wait a minute: An app, not a library? What difference will sealed make here at all?

which will have object representations of Files and Folders (both come from a common class called Entry). You as a developer for this system will be entitled to extend from File and Entry freely but you can only work with Folders and its subclasses (specialised folders) but to this system it is important you don't subclass any type of folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

So, how many types of directories may exist that you would have to mark as final? (serious question — please don't ignore it)
I don't know about you specific model, but for me, invisible directories and bundles would be all I'd be worried about — and those are basically all normal folders as well…
So, do those subclasses each have special properties? There is only a limited set of metadata a directory can have, so I expect there is no need for subclassing at all: Is there a special reason why it can't be a single class, or an enum?
This may all be useless advice that doesn't work for your case — but if I stick with the Sasquatch-metapher, this is a very blurred picture...

IMO libraries are to be written with intention in mind and I don't think it is right to use a library written to compose a PDF file to send an email (even if you're sending the PDF file attached, the right way to do it is by composition not subclassing).

How is this statement connected to the proposal?
The only way to prevent misuse of software is not to write it; and what harm is done to you as the author of a PDF-lib (btw: been there, done that — nasty format ;-) if some stupid user turns your composer into Emacs?

Additionally, someone mentioned and I went in to check about a recommendation for Java to intentionally document and enable classes to be subclasses explicitly otherwise forbid it at all and that recommendation seems to come from Oracle itself. I believe Oracle would do it to Java if it had great interest in it without consulting anyone's opinion.

good point… Oracle is widely known for its instinctive knowledge about the needs and problems of their customers — which they than tend to ignore and do something different ;-)

About the addition to the proposal to enable force unsealing, I'm completely opposed as it is just like not having any of this protection at all (why putting a lock on the door to your house if the key is under the mat?)

As long as we don't speak about commercial libraries, which are a curiosity in the Swift-cosmos:
There is no lock, there is not even a door — there is only a tiny sign that says "please don't enter", and the worst thing that could happen if you ignore it is that the original owner stops doing the housework.

If I'm not wrong at least one member of the core team already mentioned in this thread this is completely aligned with the intention of the language, so I think we should give it a go and stop trying to have/keep control of everything we touch.

Isn't this exactly what this proposal is about? Replacing freedom with control? Stop trying to keep control of everything is actually a good idea in the light of this proposal.

I appreciate that you described your case, but it didn't do anything to convince me.

Tino

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

You asked me to correct you and I shall:

Well, in the first place, I asked how many subclasses you have to "seal" manually… may I assume that it is a low number?

You asked for an example where this feature would be needed and I've provided.

No, actually you provided an example where you think the feature would be needed… but wait:
How could you write it then? Do I have a wrong interpretation of "needed", or did you write this thing in an apocalyptic future? ;-)

As I said, a concrete and real example. But I haven't seen anyone give the slightest concrete technical reason not to approve it and please don't come saying fix bugs in a library by subclassing because that's not what subclassing is for. That is a misuse of object orientation in whichever language you're working with.

At least there are many real (at least I think so) examples of problems that could be solved because sealed isn't the default now…
But as I said in another message:
All of this is not about technical reasons, but only about personal preference — and my preference is to have fun writing software, instead of struggling with bureaucracy.

Well stated and has pushed me into favoring the closed be default case. I
favor being explicit and the default being safe (you can always unseal in a
future revision if a need arises).

Also as you note it won't prevent bad implementations but it will help
library developers better bound their external surface and contract...which
if leveraged well will help with robustness, testability, and flexibility
in future revisions.

-Shawn

···

On Sun, Jul 10, 2016 at 10:53 PM Paul Cantrell via swift-evolution < swift-evolution@swift.org> wrote:

> On Jul 10, 2016, at 8:49 PM, let var go via swift-evolution < > swift-evolution@swift.org> wrote:
>
> 2. The motivation seems to be that it will force better API design.

No, that wasn’t my motivation in giving it a +1. This seems to be a common
misunderstanding in the “no” camp, so I’ll address it.

Accepting this proposal won’t turn bad API designers into good ones.
Crappy APIs are still going to be crappy with or without this. In the
immortal quote apparently due to Lawrence Flon: “There is not now, nor has
there ever been, nor will there ever be, any programming language in which
it is the least bit difficult to write bad code.”

The justification for this proposal is all about supporting the people who
are working to design library APIs right, and about maintaining consistency
with the design philosophy of Swift. To wit: in Swift, where there’s a
default choice, it’s the safe one; where there’s a consequential design
decision, it’s explicit.

Rod Brown hit the crux of it: sealed → open is safe for existing API
clients, but open → sealed is a breaking change. “Sealed” is thus the safer
choice, and “open” is a consequential design decision. Given the general
precedent and philosophy of Swift, competent API designers might reasonably
be taken aback that open is the default. In fact, given the habit Swift
encourages of leaning on compiler verification, this is a potential source
of designer error.

• • •

For those who think that discouraging inheritance by default is something
recent, or a fad, or a quirk of Swift: Josh Bloch spent over 5 pages of
Effective Java arguing against “subclassable just in case.” That was in
2001, and it was old news even back then.

Those looking for a more detailed analysis of the problems caused by APIs
allowing inheritance without designing for it should read his analysis.
It’s 15 years old, it’s Java, but it still stands. (He even gives
instructions toward the end for simulating something very much like the
here-proposed “sealed” in Java using package-private initializers.) It’s
item 15 in the book, “Design and document for inheritance or else prohibit
it.”

Cheers,

Paul

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Leonardo's example makes the case for why Swift should adopt a 'sealed' keyword that can be used to make public classes non-subclassable outside the module where they are defined, but not for why this should be the default.

Others have made these points before, but these are the two biggest reasons I can see against making public classes non-subclassable by default:

1. It is the opposite of nearly every other OOP language's behavior and the opposite of what anyone will expect who is coming to Swift after doing any OOP programming anywhere else. While I believe that Swift should be free to buck the trends of other languages where there are significant advantages, changing something this fundamental will introduce a new learning curve for even experienced programmers. The advantages better be significant, otherwise you are introducing a frustrating quirk into the language without any great benefit in exchange. But the advantages of default non-subclassability are marginal at best. Whatever advantage there is can be achieved by making it opt-in using a 'sealed' keywrod, instead of by making it the default.

As stated previously in this thread, modern languages like Kotlin do have this behaviour and base themselves on what is recommended good design in Java. So we this behaviour is not necessarily new or orthogonal to nearly every other OOP language. Secondly, I don’t agree that the advantage of default non-subclassability is marginal at best. It will have very real repercussions on the robustness and documentation of third-party libraries.

2. The motivation seems to be that it will force better API design. On average, I can't believe that it will. Assume that there are two kinds of developers: Those that make careful decisions about their API design and those that don't. The ones that make careful decisions about their API design will continue to do so - I don't see any significant improvement to their code by making non-subclassability the default.

The improvement is that extension points will be clearly and explicitly marked, instead of having to rely only on documentation (which can be lacking, even from developers that make careful decisions about their API design).

The developers who don't make careful design decisions will just go with the default - in this case they will just leave the default in place, and their public classes will not be subclassable. That doesn't improve anything, it just makes sloppy, poorly written code harder to fix in the off-chance that you are stuck working with it. In other words, quality will not improve, but productivity will suffer, because it will be harder to develop workarounds for the problems that will inevitably appear in even the best-designed APIs.

Here, I also disagree. Imagine we are talking about an open-source library on GitHub. People will complain about the lack of sub-classability through issues and pull-requests. This will hopefully be enough to get discussions going on what is wrong with the API to warrant subclassing and exactly what the subclassing extension points should be. This discussion will happen around many libraries and will help educate people to think carefully about subclassing.

3. It is a bad interpretation of the stated goal that Swift should help developers produce "safe code." Some folks seem to believe that this means that the language should protect people from themselves. If I am using your API in my code and I screw it up by subclassing something that I shouldn't have, that is somehow a language defect. It is not a language defect - it is me being an idiot.

This argument could very well be transposed to defend C's memory-management and does not stand for me. A language should always strive to protect developers from their own mistakes. If that was not the case, languages would never have introduced garbage collection, ARC, optionals, etc...

Don't spend a lot of time trying to make a language idiot-proof - idiots are geniuses and you will never outsmart them. Personally, when I read that Swift helps produce "safe code", what that means primarily is that it has a type system that helps reveal the vast majority of bugs that would otherwise go unnoticed until runtime. In other words, safety is related to discovering hidden flaws in the program. (Type safety isn't the only feature that helps with this, but it is perhaps the main one.) But this whole issue of default non-subclassability doesn't fall into that category of "safety" at all. It doesn't help a programmer produce safer code. The same hidden flaws will persist whether non-subclassability is the default or not. The difference is that those same hidden flaws will be more difficult to deal with after the fact.

How can it not help programmers produce safer code? By not subclassing a brittle class, it does protect them from internal modifications in that superclass.

···

On 11 Jul 2016, at 03:49, let var go via swift-evolution <swift-evolution@swift.org> wrote:

To sum it up, +1 for introducing a 'sealed' keyword, but -1 for making it the default behavior for public classes.

On Sun, Jul 10, 2016 at 12:18 PM Leonardo Pessoa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Should I assume then you want so much this proposal to be dropped you didn't even mind to look for the example so you wouldn't have to admit this proposal is needed? Fine, here is the whole of that example.

I'm currently working on an app which will have object representations of Files and Folders (both come from a common class called Entry). You as a developer for this system will be entitled to extend from File and Entry freely but you can only work with Folders and its subclasses (specialised folders) but to this system it is important you don't subclass any type of folder. Without this proposal I would have to create workarounds to prevent you from doing that while still allowing me to subclass while playing a lot of finals everywhere. And so far I would have to allow you to subclass Folder itself (at least) but you would complain (and possibly file a bug report to me) because it would not be working properly because your classes would not benefit from the workaround. In this case, if I could subclass internally but prevent you from doing it, you could complain I'm not allowing you to do whatever you want but you wouldn't complain my code doesn't work properly (it does, you just won't know it).

There may be several more examples but this is one I'm facing right now, so I can assure you it is a true example. IMO libraries are to be written with intention in mind and I don't think it is right to use a library written to compose a PDF file to send an email (even if you're sending the PDF file attached, the right way to do it is by composition not subclassing).

Additionally, someone mentioned and I went in to check about a recommendation for Java to intentionally document and enable classes to be subclasses explicitly otherwise forbid it at all and that recommendation seems to come from Oracle itself. I believe Oracle would do it to Java if it had great interest in it without consulting anyone's opinion.

About the addition to the proposal to enable force unsealing, I'm completely opposed as it is just like not having any of this protection at all (why putting a lock on the door to your house if the key is under the mat?)

Swift doesn't have to follow on the footsteps of any language but what is best for the intention the language was created for. If sealed by default goes in that direction, then we should have it not looking back. The same goes if we decide this is not taking the language in its intended direction. If I'm not wrong at least one member of the core team already mentioned in this thread this is completely aligned with the intention of the language, so I think we should give it a go and stop trying to have/keep control of everything we touch.

L
From: Tino Heth via swift-evolution <mailto:swift-evolution@swift.org>
Sent: ‎10/‎07/‎2016 01:55 PM
To: swift-evolution <mailto:swift-evolution@swift.org>
Cc: Jean-Daniel Dupas <mailto:mailing@xenonium.com>
Subject: Re: [swift-evolution] [Review] SE-0117: Default classes to benon-subclassable publicly

Two days ago, I challenged the supporters of this proposal to show a singe persuasive example to illustrate that this proposal could actually improve something.
I got a single reply — which did not contain an example, but just the claim that there is one…
Imho that alone should be enough to cancel the whole thing, because even if there are cases which cannot be repelled with the simple advice "just don't subclass", this would only be a basis to start talking about the actual pros and cons.

So for me, the promised benefits are less likely than the existence of Bigfoot:
I guess there are at least several hundred people who swore they have seen him, and there are even some blurry photos ;-)

Of course, it is impossible to come up with an unquestionable argument for the change — and it's also impossible to prove the opposite, because the whole debate makes as much sense as arguing wether raisins are tasteful or terrible; it's nothing but personal preference, and the only thing we can hope for is that the bias of those who will decide this proposal isn't at odds with the needs of the majority.

If we can agree that it is not about facts, but about opinion, there are still fundamental arguments against SE-0117:
Those who have issues with subclassing can just resign from it (as users of a library), and they can annotate their classes to dictate their usage (as an author) — but if you think subclassing is still a good tool, you can't do anything with a sealed class.
Additionally, please note that those who ask for stricter rules and more regulation have many reasons to be happy with the status quo:
You can subclass neither structs nor enums, and by default, you can't inherit from a framework-class as well, because it is internal — and yet they yell for more.

Swift claims to be opinionated, not to aim for compromise — but if plain old OO isn't compatible with the ideals of the language, it would be more honest to just completely remove inheritance instead of slowly crippling it's possibilities.

- Tino
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Regards
(From mobile)

2. The motivation seems to be that it will force better API design.

No, that wasn’t my motivation in giving it a +1. This seems to be a common misunderstanding in the “no” camp, so I’ll address it.

Accepting this proposal won’t turn bad API designers into good ones. Crappy APIs are still going to be crappy with or without this. In the immortal quote apparently due to Lawrence Flon: “There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code.”

The justification for this proposal is all about supporting the people who are working to design library APIs right, and about maintaining consistency with the design philosophy of Swift. To wit: in Swift, where there’s a default choice, it’s the safe one; where there’s a consequential design decision, it’s explicit.

+1. This is exactly why sealed is the default that fits best with the rest of the defaults in Swift. They are permissive within a module and require explicit choices where external contracts are involved.

Rod Brown hit the crux of it: sealed → open is safe for existing API clients, but open → sealed is a breaking change. “Sealed” is thus the safer choice, and “open” is a consequential design decision. Given the general precedent and philosophy of Swift, competent API designers might reasonably be taken aback that open is the default. In fact, given the habit Swift encourages of leaning on compiler verification, this is a potential source of designer error.

• • •

For those who think that discouraging inheritance by default is something recent, or a fad, or a quirk of Swift: Josh Bloch spent over 5 pages of Effective Java arguing against “subclassable just in case.” That was in 2001, and it was old news even back then.

Those looking for a more detailed analysis of the problems caused by APIs allowing inheritance without designing for it should read his analysis. It’s 15 years old, it’s Java, but it still stands. (He even gives instructions toward the end for simulating something very much like the here-proposed “sealed” in Java using package-private initializers.) It’s item 15 in the book, “Design and document for inheritance or else prohibit it.”

Agree. The best practice has been around for some time, although it sounds like it is not yet widespread as it could be (especially in-depth knowledge of the rationale behind it).

What is relatively new is the opportunity to embrace it in the design of a (sure to be) popular and widely used language that carries most of the traditional OO facilities. This is a great opportunity IMO.

I find surprising to that one would sign up for what basically amounts to 'compiler take my freedom away as I do not feel I can bare the responsibility it places on me'. To me, Joshua Bloch's message was never as an appeal to the javac teams to suppress freedom, but to developers to become cognizant of its consequences and strive to write better code. But it seems to be a human trait throughout history to want to relinquish our individual freedom for the comfort of someone else being responsible.

···

On Jul 11, 2016, at 5:00 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 10, 2016, at 9:53 PM, Paul Cantrell via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 10, 2016, at 8:49 PM, let var go via swift-evolution <swift-evolution@swift.org> wrote:

Cheers,

Paul

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The justification for this proposal is all about supporting the people who are working to design library APIs right, and about maintaining consistency with the design philosophy of Swift. To wit: in Swift, where there’s a default choice, it’s the safe one;

I challenge this claim:
Safety is valued, but Swift cares (and should care!) about pragmatism as well… the most obvious example that comes to my mind are arrays, which have no safeguards that stop you from accessing elements that aren't there.

where there’s a consequential design decision, it’s explicit.

When there is no explicit statement about subclassiblily, it's reasonable to assume that there hasn't been a consequential design decision… but sadly, discussion like this mainly driven by dogmatism, because there is no evidence for either side.

I think folks are going in an unprofessional direction in this thread, let
bring it back to a more positive direction please.