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

Brent Royal-Gordon brent at architechies.com
Tue Dec 22 00:31:40 CST 2015

> In my considerable experience with C++, that is not at all where we are today.  Increasingly, C++ is becoming seen as a language for high-performance computing, and people working in that area learn that they don't want to pay for virtual dispatch when they don't have to.  It is true that for some of them, reflexive use of OOP is hard to shake, but they do learn eventually.

Is Swift's goal to be a perfect language for high-performance computing? I thought it was to be a language that scales from scripting to systems programming, with a nice sweet spot around application development.

For application development, speed is certainly good, but it is not the priority. We want Swift to go fast wherever we can get those speed gains without much cost, of course, but I worry that the cost of this proposal is too high. Just imagine going through UIKit and marking every class inheritable *by hand*—no cheating with a script—and you'll have some idea of the additional burden you'll be imposing on developers as they write their code. The proposals that every single method should be explicitly marked as overridable are even worse; frankly, I don't think I'd want to use Swift if you forced me to put a `virtual` keyword on every declaration.

I worry that the team's use of Swift to build the standard library, and their close association with teams building OS frameworks, is biasing the language a little bit. I think that, in all likelihood, most Swift code is in individual applications, and most libraries are not published outside of a single team. If I'm right, then most Swift code will probably be quite tolerant of small but technically "breaking" ABI changes, such as making a class `final`, or (as mentioned in another thread) making a closure `@noescape`.

That won't be true of published library code, of course. But published library code is a small minority of the Swift code people will write, and it already will require greater scrutiny and more careful design. 

There is already a good opportunity to reflect on whether or not an API should be `final`. It's when you put the `public` keyword on it. I think programmers will have a better, easier time writing their code if, in this case, we put a little bit of trust in them, rather than erecting yet another hoop they must jump through.

Perhaps we could even provide a "strict interfaces" mode that published frameworks can turn on, which would require you to declare the heritability of every class and member. But even that may not be a good idea, because I also suspect that, in the field, most published libraries probably have to be extended in ways the library's author did not expect or anticipate. 

This means doing some dangerous overriding, yes. But a UI that breaks after an iOS upgrade is not nearly as dangerous to my business as a three-month delay while I reimplement half of UIKit because someone in Cupertino thought they knew what I need better than I do and turned off—or even worse, *left turned off without a single thought*—subclassing of UIBarButtonItem.

The bottom line is this: Your users like Swift's strictures when they're helpful. *This stricture is not helpful.* Library users don't accidentally subclass things, and with the `override` keyword in Swift, they don't accidentally override them either. And where it truly is important, for safety or for speed, to prevent subclassing, we already have `final`. Making it the default is less safety than suffering.

Brent Royal-Gordon

More information about the swift-evolution mailing list