[swift-evolution] An Alternative for Extensibility Modifiers
jhull at gbis.com
Tue Jul 12 04:12:36 CDT 2016
With all the controversy around proposal 0117, I thought I would take a stab at an alternative approach that attempts to balance the concerns of both sides of the argument. I don’t know that it would be everyone's first choice, but I think/hope it would be acceptable to the vast majority.
Take a look here and let me know if you think it is worth flushing out:
The basic idea (for those who hate clicking links) is to create 3 levels of extensibility:
• Open - The class or method is open to be extended through subclassing/override.
• Sealed - Attempting to subclass/override the class/method will result in a compiler error saying that it is not intended to be extended. Using the ‘unsafe' keyword will allow compilation.
• Final - The class or method can not be subclassed/overridden. Attempting to do so will result in a compiler error.
These would be orthogonal to access modifiers. Thus you would write ‘public open’, which is admittedly two words… but together they are actually shorter than the single ‘subclassable’ keyword
You can also specify different levels of extensibility at different levels of visibility (e.g. ‘public final internal(open)’)
The default would be ‘sealed internal(open)’ which means it is publicly sealed, but open within the defining module. This is similar to the default of 0117, except it allows overriding using the ‘unsafe’ keyword (where the user explicitly acknowledges that subclassing/overriding is not supported by the API).
Thus, we lose some compiler optimizations in the default case (vs 0117), but these can easily be regained by explicitly marking parts of the API as final. The semantic meaning of the 0117 default is kept, with an escape hatch for problematic API. Thoughtful framework writers would go through and mark API as either ‘public open’ or ‘public final’. Less thoughtful framework authors would still get feedback asking them to do so, since nobody likes having the word ‘unsafe’ in their code when they don’t have to.
This design feels much Swiftier™ to me because it has opt-out safety and opt-in risk. It protects you from accidentally causing trouble, but gets out of your way when you tell it you know what you are doing.
More information about the swift-evolution