> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> -1 for the fact that if all devs can write working code, fewer can do it in a 
> clear structured fashion that is well designed for extensibility.

This sounds more like an argument for having sealed classes than not. As the 
proposal points out in the motivation, if the base class is not designed with 
subclassing in mind then overriding methods can result in unintended behavior 
(e.g. crashing, or other bugs).

Mark

> A couple months ago I even ran into difficulties when trying to extend 
> AlamoFire because some things had not been designed as cleanly as they could 
> have been to make extending it easy. So if the default is now that everything 
> becomes non-extensible but default, it is going to complicate (and partially 
> defeat the purpose of) reusing libraries.
> Regards
> (From mobile)
> 
> On Jun 28, 2016, at 2:11 AM, Michael Ilseman via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> I was also referring to how we present Objective-C classes in Swift. That 
>> is, if a Swift user tries to subclass an Objective-C-imported class, then 
>> we’d take into account sealed-ness in order to issue an error/warning, etc. 
>> If you are also proposing a Clang attribute for this, e.g. ‘swift_sealed’, 
>> to import as sealed (meaning issue an error if Swift users try to subclass 
>> it), then that should be spelled out as well. I don’t have an opinion on 
>> whether this is a good idea yet, just pointing out some more directions to 
>> explore. In general it feels like your proposal could use more fleshing out.
>> 
>> 
>>> On Jun 27, 2016, at 5:08 PM, Javier Soto <javier....@gmail.com 
>>> <mailto:javier....@gmail.com>> wrote:
>>> 
>>> That is a very good point, it should be explicitly mentioned in the 
>>> proposal. My thought would be that since in the Obj-C runtime it's not 
>>> possible to guarantee a class won't have subclasses, or that a method is 
>>> not overriden, Obj-C classes would be imported as open. 
>>> 
>>> On the Swift side, I think today it's possible to declare a "public final 
>>> @objc class", but you can still inherit from it from Obj-C, right? My hunch 
>>> would be that that should be disallowed, but perhaps there's a reason why 
>>> it's allowed today. 
>>> On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman <milse...@apple.com 
>>> <mailto:milse...@apple.com>> wrote:
>>> Could you elaborate on how we should treat classes imported from 
>>> Objective-C or CF-style C? That is, do we always annotate them as being 
>>> “open” because those paradigms permit subclassing anywhere, or do you 
>>> propose some kind of recommended “sealed” audit, or what?
>>> 
>>> 
>>>> On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> -- 
>>> Javier Soto
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> 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

Reply via email to