[swift-evolution] [swift-evolution-announce] [Review #3] SE-0117: Allow distinguishing between public access and public overridability

Nevin Brackett-Rozinsky nevin.brackettrozinsky at gmail.com
Thu Jul 21 17:05:43 CDT 2016


>
> I agree that it would make sense to be able to say "I allow subclasses,
> but they
> don't get to override any of my methods unless I say so, even things I
> inherit".
> But that feels like a refinement.


Well, we can already achieve that by writing,

  public final func f() -> Int { return _f() }
  internal func _f() -> Int { return 42 }

That way subclasses in the module can override _f to change the behavior of
f, while outside they cannot. So we can already accomplish “an open member
of a base class is sealed by a subclass”.

What we *can’t* do, either now or with the proposal, is have a sub-subclass
*re-open* that member:

open class A { open var x: Int //... }
open class B: A { override final var x: Int { return _x } }
open class C: B { override open var x: Int { return 16 } }   // error:
cannot override `final` member

For that we would need either an explicit `sealed` keyword, or the ability
to override an `open` member as `public` (non-open), which class B could
use here.

Nevin


On Thu, Jul 21, 2016 at 4:22 PM, John McCall via swift-evolution <
swift-evolution at swift.org> wrote:

> On Jul 21, 2016, at 1:04 PM, Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
> on Thu Jul 21 2016, John McCall <swift-evolution at swift.org> wrote:
>
> On Jul 21, 2016, at 10:47 AM, Dave Abrahams via swift-evolution
> <swift-evolution at swift.org> wrote:
> on Thu Jul 21 2016, Matthew Johnson
> <swift-evolution at swift.org
> <mailto:swift-evolution at swift.org <swift-evolution at swift.org>>>
>
>
> wrote:
>
> * What is your evaluation of the proposal?
>
>
> +1 to the first design.  I think this is a great solution that
> balances the many considerations that have been raised on all sides of
> this issue.  `open` is 2 characters shorter than `public` so
> complaints about boilerplate are no longer valid.  `internal` is the
> “default” - neither `public` nor `open` are privileged as a “default”
> for publishing API outside of a module.
>
> I am interested in language enhancements such as exhaustive pattern
> matching on classes and protocols which rely on knowledge of the full
> class hierarchy.  Such enhancements will be far more useful if the
> language supports non-open, non-final classes.
>
> There are design techniques that would require additional boilerplate
> if we cannot have non-open, non-final classes.
>
> Most importantly, requiring library authors to choose `public` or
> `open` provides important documentation value.  Users of the library
> will know whether the author intends to support subclasses or not.
>
>
> I think this reasoning is flawed.
>
> If you make any methods overridable outside your module (“open”),
> obviously you mean to allow subclassing outside the module.  If you have
> no open methods, there's absolutely nothing you need to do to “support
> subclasses,” and from a design point-of-view, there's no reason to
> restrict people from subclassing.
>
>
> Superclasses can have superclasses, which can themselves have open methods.
> This is, in fact, quite common for Cocoa programmers.
>
>
> Okay, good point.
>
> Making a class non-subclassable seems like a pretty indirect way to say
> “not even inherited methods should be overridden outside the defining
> module,” though.
>
>
> Wouldn't we prefer to have a way to hide the inheritance relationship
> (and thus prevent overriding of inherited methods) outside the module?
> Or are these independently useful axes?
>
>
> I agree that it would make sense to be able to say "I allow subclasses,
> but they
> don't get to override any of my methods unless I say so, even things I
> inherit".
> But that feels like a refinement.
>
> John.
>
>
>
>
> John.
>
>
> The only reasons I can see for allowing people to prevent non-final
> classes from being subclassed outside the module in which they are
> defined are:
>
> 1. It feels like a nice point of control to have.
>
> 2. Marginal performance gains as noted in the proposal
>
> I personally don't find these to be convincing.  #1 in particular seems
> like a poor way to make language design decisions.  If we decide to add
> this point of control, I'll justify it to myself in terms of #2.
>
> P.S., I can live with either alternative; it's just important to me that
> we understand the situation clearly when evaluating them.
>
> HTH,
>
> --
> Dave
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> <mailto:swift-evolution at swift.org <swift-evolution at swift.org>>
> https://lists.swift.org/mailman/listinfo/swift-evolution
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> --
> Dave
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160721/8b203827/attachment.html>


More information about the swift-evolution mailing list