> On Jun 29, 2016, at 10:17 PM, L. Mihalkovic <laurent.mihalko...@gmail.com> 
> wrote:
>> On Jun 29, 2016, at 8:39 PM, Vladimir.S via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> How about `public(extensible)` ?
>> 
>> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
>>>> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
>>>> really make sense. `internal` declarations are always sealed.
>>> 
>>> Right.
>>> 
>>> If "sealed" is the default behavior for public classes and methods — and I 
>>> don't think the modifier is worth adding unless it's the default
> 
> What a jump... I am very curious about this rational that seems so obvious to 
> you?

There are a thousand different ways to add minor variations on language 
features.  In almost every single thread of any length on this list, you can 
find someone who got attached to a slightly different feature from the one that 
eventually got picked, and often you can find them asking why we didn't just 
add that, too, maybe under a different name or using different syntax.  If we 
added every single one of those, the language would not be better, it would 
just be absurdly, dauntingly complex.  We have to look at these kinds of 
additive features with a very critical eye and decide how much code will really 
benefit from it.

In our experience, idiomatic Swift libraries don't center that much around 
classes, and especially not around class inheritance.  Value types are usually 
a better and more efficient data representation than juggling shared mutable 
state, and protocols are a cleaner and much more robust tool for polymorphism 
than overriding methods.  Classes are useful for modeling values with 
"identity", but even then, the class itself can often be final: when its 
operations need to be polymorphic, it's usually better to just pass in a 
closure or an existential, because piling up overrides turns code into 
spaghetti very quickly.

That doesn't mean we don't want to add good tools for classes, of course, but 
inheritance and overriding have a lot of subtle interactions, both at a low 
level with other language features and at a high level with any attempt to 
establish basic object invariants.  Programmers want an endless variety of 
language tools for ensuring that overrides satisfy the contract correctly — 
"require the super method to be called", "require the super method to be called 
in exactly this way", "require the super method to be called unless the method 
exits early", "only allow calls to these specific other methods", "require this 
method to be called before doing anything else", ad infinitum.  The only way we 
could possibly support all that is by first adding some massive new contracts 
feature and then embellishing it with a ton of inheritance-specific logic; in 
other words, everything with classes quickly balloons into a a huge research 
project, because (in my opinion) overriding is just an inherently clumsy tool.

So when you look at something like 'sealed' as an opt-in modifier, you have to 
think carefully about who is actually going to use it.  It's an explicit 
modifier that limits inheritance, but we already have 'final', so it's only 
useful when the library wants to provide its own private subclasses, but 
doesn't want to commit to full public inheritability.  How often does that 
happen, really?  Are we adding this feature for a handful of developers in the 
entire world, most of whom could probably find another solution to their 
problem?  And that's for 'sealed' on a class — are we really supposed to expect 
that someone will unseal a class, but individually protect all the methods and 
properties they don't want overridden?

In contrast, 'sealed' as a default is a conservative protection against 
forgetting to add 'final' (which will quickly get caught if the class is truly 
meant to be subclassed), and applied method-by-method it encourages the 
developer to think carefully about where they want the extension points to be 
on their class.  Moreover, it enables a number of interesting language 
enhancements which can only be done safely with complete knowledge of the 
inheritance tree, and it significantly improves performance without adding any 
invasive annotations.  And because it's already there as the default behavior, 
that handful of developers who actually need it specifically can get it for 
free.

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

Reply via email to