[swift-evolution] Final by default for classes and methods

Roopesh Chander roop at roopc.net
Tue Dec 22 04:48:37 CST 2015


> the dynamic nature and possible overridability of even things that Apple
doesn’t
> specifically intend to allow overriding is one of the primary reasons why
AppKit has
> survived for 20+ years and spawned arguably the most successful
application
> framework in history in UIKit.

Aren't we mixing up two different issues here? "Having a default final for
Swift classes" should be treated as a separate issue from "Apple frameworks
should stay overridable".

They are different issues because:

 (a) Even if final was not the default, any framework vendor can mark its
classes final. The only thing we can do is trust Apple to maintain the
status quo (monkey-patchable) for its current and future frameworks - we
can't just hope they'll forget to override a default of non-final.

 (b) If / when there's a Swift-written binary framework, if it has to
expose its methods to Objective-C (with @objc / dynamic), it would have to
become monkey-patchable.

So, while we definitely need the ability to override Apple's frameworks
(now and in the future), that DOES NOT count as a reason to say that final
shouldn't be the default.

If we take that out of the equation, this proposal can be seen in terms of
these questions:

 1. Within a module, should I be able to override my own classes / methods
by default, or should I have to explicitly mark those classes as
overridable to do that?

 2. If I'm releasing a Swift binary framework, and I haven't yet thought
about which classes / methods should be overrideable, should I release it
in
 everything-is-overridable mode, or in nothing-is-overridable mode?

    (Note that if I make a release now in everything-is-overridable mode, I
can't make a binary-compatible release in the future with reduced
overridability.)

 3. If I'm using a third-party (non-Apple) Swift binary framework, and if
the framework author hadn't really thought about which classes / methods
should be overrideable, would I want the power to override everything in
the framework now?

    (Note that if I get that power, I forgo all hope of getting a
binary-compatible update to the framework with correct annotations about
which classes can be safely overridden and which aren't meant to be
overridden.)

In questions 2 & 3, I'm focusing only on binary frameworks because if the
source code was available, it would be possible to modify the source to
override whatever we wanted - so overriding or patching would be possible,
only maybe inconvenient.

Personally, my answers for the above questions will be:

 A1: Within my own module, I'd like to have all classes overridable by
default
 A2: If I haven't thought about overridability in my framework, I'd rather
release it now in nothing-is-overridable mode, and retain the ability to
fix it in an update.
 A3: Ideally, I'd like to be able to override everything in the framework I
use, but if that implies that I can't get a binary-compatible fix to the
framework, maybe I can live without that overridability.

Therefore, I'd support a proposal to make classes in the module's public
interface final-ized by default.

As to naming/syntax, I suggest this:

    public class C1 { } // Can't subclass

    public class C2 {   // Can subclass because it has an
                        // overridable method
        func f1() { }             // Can't override
        overridable func f1() { } // Can override
    }

    overridable public class C3 { // Can subclass
        func f1() { }             // Can override
        func f1() { }             // Can override
    }

Thanks,
roop.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151222/64d3faac/attachment.html>


More information about the swift-evolution mailing list