All bike-shedding aside, I see two parts of this proposal and I come down on 
different sides for the two.

1. Introducing a new class modifier that acts as final outside the defining 
module
2. Changing the default to this new modifier (and thus also introducing a third 
explicit class modifier that represents the current default (non-final) 
behavior.

I think that the behavior of the new proposed modifier is useful. I imagine 
that it would allow for the same type of optimizations as a final class 
(assuming whole module optimizations) while remaining flexible within the 
module itself. We’re currently using a public protocol with one or more 
internal non-final classes to achieve similar results in the specific scenario 
where we want a unified external type. 

On the topic of changing the default, I’m against for the same reasons that was 
brought up in the discussion of making final the default. Since those reasons 
were mostly about usage outside of the same module, I find them equally valid 
in this case.

- David


> On 28 Jun 2016, at 00:40, Javier Soto via swift-evolution 
> <[email protected]> wrote:
> 
> Hello!
> 
> I sent this as a PR <https://github.com/apple/swift-evolution/pull/376> on 
> the swift-evolution repo, but we never had any discussion about it on-list, 
> besides a long time ago 
> <http://thread.gmane.org/gmane.comp.lang.swift.evolution/9702/focus=9708>. 
> Here's the first draft of the proposal:
> 
> 
> Sealed classes by default
> 
>  
> <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#introduction>Introduction
> 
> Introduce a new sealed class modifier that makes classes and methods final 
> outside of the module they're declared in, but non-final within the module.
> 
>  
> <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#motivation>Motivation
> 
> It is not uncommon to have a need for a reference type without needing 
> inheritance. Classes must be intentionally designed to be subclassable, 
> carefully deciding which methods are the override entry-points such that the 
> the behavior remains correct and subclasses respect the Liskov substitution 
> principle <https://en.wikipedia.org/wiki/Liskov_substitution_principle>.
> Defaulting to non-final allows the author of a class to accidentally leave 
> the visible methods open for overrides, even if they didn't carefully 
> consider this possibility.
> Requiring that the author of a class mark a class as open is akin to 
> requiring symbols to be explicitly public: it ensures that a conscious 
> decision is made regarding whether the ability to subclass a class is part of 
> the API.
>  
> <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#proposed-solution>Proposed
>  solution
> 
> New sealed (actual name pending bike-shedding) class modifier for classes and 
> methods which marks them as only overridable within the module they're 
> declared in.
> sealed becomes the default for classes and methods.
> New open (actual name pending bike-shedding) class modifier to explicitly 
> mark a class or a method as overridable.
>  
> <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#detailed-design>Detailed
>  design
> 
> Code Examples:
> 
> /// ModuleA:
> 
> /// This class is `sealed` by default.
> /// This is equivalent to `sealed class SealedParentClass`
> class SealedParentClass {
>     /// This method is `sealed` by default`.
>     func foo()
> 
>     /// This raises a compilation error: a method can't have a 
> "subclassability"
>     /// level higher than that of its class.
>     open func bar()
> 
>     /// The behavior of `final` methods remains unchanged.
>     final func baz()
> }
> 
> open class OpenParentClass {
>     /// This method is `sealed` by default`.
>     func foo()
> 
>     /// Overridable methods in an `open` class must be explicitly marked as 
> `open`.
>     open func bar()
> 
>     /// The behavior of a `final` method remains unchanged.
>     final func baz()
> }
> 
> /// The behavior of `final` classes remains unchanged.
> final class FinalClass { }
> /// ModuleB:
> 
> import ModuleA
> 
> /// This raises a compilation error: ParentClass is effectively `final` from
> /// this module's point of view.
> class SubclassA : SealedParentClass { }
> 
> /// This is allowed since `OpenParentClass` has been marked explicitly `open`
> class SubclassB : OpenParentClass {
>     /// This raises a compilation error: `OpenParentClass.foo` is
>     /// effectively `final` outside of `ModuleA`.
>     override func foo() { }
> 
>     /// This is allowed since `OpenParentClass.bar` is explicitly `open`.
>     override func bar() { }
> }
>  
> <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#impact-on-existing-code>Impact
>  on existing code
> 
> This would be a backwards-breaking change for all classes and methods that 
> are public and non-final, which code outside of their module has overriden. 
> Those classes/methods would fail to compile. Their superclass would need to 
> be changed to open.
>  
> <https://github.com/JaviSoto/swift-evolution/blob/a46877afb0302d2b03fa493255f5ced04ccb7f34/proposals/0000-sealed-by-default.md#alternatives-considered>Alternatives
>  considered
> 
> Defaulting to final instead: This would be comparable to Swift defaulting to 
> private, as opposed to internal. Just like internal is a better trade-off, 
> sealed by default also makes sure that getting started with Swift, writing 
> code within a module, doesn't require a lot of boilerplate, and fighting 
> against the compiler.
> -- 
> Javier Soto
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to