[swift-evolution] [final revision] SE-0117: Allow distinguishing between public access and public overridability

John McCall rjmccall at apple.com
Tue Aug 2 12:15:09 CDT 2016


> On Jul 27, 2016, at 3:06 PM, Chris Lattner <clattner at apple.com> wrote:
> Proposal Link: https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> 
> The third review of "SE-0177: Allow distinguishing between public access and public overridability" ran from Active review July 21...25. The proposal has been *accepted with revisions*.
> 
> This proposal was far better received by the community than previous versions of the proposal, and the “first design” was the favored path within it.  However, there were some concerns raised about the complexity of the model, stemming from non-obvious combinations like “open private”.  As such, the core team has requested that the proposal be revised to make “open” function as another access control specifier.  “open” is now simply “more public than public”, providing a very simple and clean model.
> 
> John has already revised the proposal to the new model, I encourage you to read it if you haven’t already.
> 
> Thank you to John McCall and also Javier Soto for driving this discussion forward!  John is already working on an implementation of this now.

I'm resurrecting this thread to point out some minor revisions / clarifications that came up during implementation.

The first is that the accepted proposal contained "temporary" restrictions that required (1) open classes to subclass open classes and (2) open methods to override open methods.  (2) is actually inconsistent with our existing access-control rules about overrides: the overridden method doesn't even have to be public.  Making a method open in a subclass shouldn't force you to expose it in your superclass.  Therefore, we have lifted this restriction.  (1) is consistent with the access control rule on subclasses, so it has been conservatively kept; we're still open to reconsidering this in the future.

The second is that the proposal wasn't clear about how open interacts with initializers.  There are many things about our current class-initialization design that are unsatisfactory, but we are not going to fix them in Swift 3.  However, as a general matter, the clearest mental model for initializers is that every class provides its own, independent interface for constructing complete-objects / base-subobjects of that class.  The initializers in each class are formally distinct from the initializers in their subclasses, even when they happen to have the same signature; they are not in any real sense "overrides" (even if in some cases we do currently require the "override" keyword).  This is true even for required initializers, which merely state a requirement that all subclasses must provide a complete-object initializer with a particular signature, rather than expressing a real relationship between those initializers at each level.  Furthermore, it is understood that constructing an object of a subclass necessarily involves delegating to that subclass; subclasses must always be able to initialize their portions of constructed objects.  For all of these reasons, it is correct for initializers to not participate in open checking: they cannot be declared open, but correspondingly there are no restrictions on what initializers can be defined in a subclass, even if they have the same signature as an initializer from a superclass.

I have updated the proposal to reflect this.

John.


More information about the swift-evolution mailing list