It seems like there are two views on this – perhaps it’s largely people who value freedom to modify other people’s libraries vs. library authors who value freedom to modify their own libraries without breaking other people’s code…
(Personally I’m more in the former camp.)
In any case, it seems like a viable solution would have to satisfy both camps, and of course not break existing code.
Maybe we need three levels - (a)
final for “if you extended this things would likely break, so just NO,” but also (b) “this is meant to be extended at will” (e.g., JComponent) and © “if you extend this, you’re taking your life into your own hands.” It seems reasonable to make the first two explicit, since they are the most opinionated. I think © pretty much describes how things work very often already. So we could say © is the default. On the other hand, adding a new keyword for (b) (like
virtual) seems too big of a change, even if it weren’t a breaking change.
Add an annotation
@open (or whatever bikeshed color) to document a class as an open hierarchy. A class with that annotation is in category ©, otherwise (without
final) it’s in (b).
In Dotty, traits can have parameters, and support for trait parameters may be coming even in Scala 2.x, which begs the question why have classes if traits can do everything classes do and aren’t restricted to single inheritance. So we say traits are (of course) in (b), and all (non-
final) classes would be considered ©, and discouraged to extend.
In any case, we don’t want to be too harsh on people in the © camp. So extending something in © shouldn’t be an error, or even flood the build log with warnings by default. Instead, either collapse the warnings by default like is currently done with deprecation, feature, and unchecked warnings, or else make the warnings opt -in with -Xlint. If someone wants to kickstart it they can do it as a library / compiler plugin, or add support to wartremover or the like, and promote it wherever possible.