[swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly
jordan_rose at apple.com
Mon Jul 11 16:08:11 CDT 2016
> On Jul 11, 2016, at 04:34, Tino Heth <2th at gmx.de> wrote:
> I haven't read the whole Library Evolution document, but one important part is written right at the top:
>> This model is largely not of interest to libraries that are bundled with their clients (distribution via source, static library, or embedded/sandboxed dynamic library, as used by the Swift Package Manager <https://swift.org/package-manager/>)
> So there are compelling arguments to "seal" the Apple-libraries, and it's reasonable to enforce sealing on them.
> But if sealed is the right default for those libraries, it is not automatically the right default for all other libraries out there, because those are developed in a completely different manner.
> So, instead making sealed the default for Swift, I believe it is much more sound to just make it the default for the standard frameworks:
> This doesn't break compatibility, it's imho more convenient for the majority, and I guess there is enough manpower to manage the annotations for Cocoa and other frameworks (which is tedious labor for single developers, but no issue for a large company).
The binary compatibility concerns are less important, but the ability of a library author to reason about behavior is still critical. Here’s a scenario I really don’t want to see happen:
1. Client X adds a dependency on library A, via the package manager. They override a public method in library A to get the behavior they want.
2. Library A ships an update which fixes many bugs and security issues, and happens to eliminate the internal calls to the public method A was using. That is, overriding Athat method no longer has any effect within library A; only clients see the difference.
3. The developer for client X goes to their manager and asks for time to fix the issue. The manager tells them not to update right now, but maybe after this next release.
4. Client X never gets a new version of Library A ever again.
This hypothetical scenario happened because the client and the library had differing notions about what you could do with this particular public method. From the library point of view, this shouldn’t be a source-breaking change because they never expected it to do anything; from the client point of view, the program does a perfectly normal thing of overriding a public API and the library has capriciously broken it.
I guess another way of saying this is that library authors avoid these miscommunications by "under-promising”, and if that “under-promising” is something that’s actually in the language instead of maybe/maybe-not being documented, then both sides are much more likely to be on the same page.
>> Am 11.07.2016 um 05:38 schrieb Jordan Rose via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>> While an overridable method may have particular preconditions and postconditions, it’s possible that the overrider will get that wrong, which means the library author can no longer reason about the behavior of their program.
> Once again a situation where we have to differentiate wether we encourage open source or not:
> In OS, users of a library become the allies of its author — they can put stress on his model, they can find its flaws and they can show him how to improve.
> The ability to take a piece of code and start playing with it is a fantastic trait, and this is actively discouraged by imposing limits not because they make sense, but only because the original author didn't take the time to reason about the status.
This is completely true, but I don’t see it as having much to do with subclassing. If a library is open source, most of your “playing with it” will be modifying the original code, not using a subclass. This is especially true given how many Swift libraries are made up of just structs, enums, and protocols. Additionally, “build for testing” will also allow subclassing sealed classes (though not final classes, since the ‘final’ is part of the semantics rather than just controlling access).
> For software that grows "organically", documentation is more useful than simple rules...
> I like the concept of version blocks, and it could work in the other direction as well: We could have a "experimental"-modifier that would give the library author a way to offer hints for its clients, but leaves the final decision up to them. This would be much more granular than a plain "final" which not only protects those who want to stay on the safe side, but also repels the bold developers who'd willingly help improving the code in question.
If you were writing a library, what would make you decide between “experimental” and not?
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the swift-evolution