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

David Owens II david at owensd.io
Thu Jul 21 12:52:50 CDT 2016


What is your evaluation of the proposal?
I think the philosophical direction of the proposal is good, though I still don’t like the actual implementation details. There are two concepts here:
the ability to subclass
the ability to override members

Having both of these concepts annotated with `open` is confusing as they do different things. Marking a class as open does **not** provide the ability to override. However, marking a member as `open` would provide the ability to override. These are two related but different concepts.

I see no reason why `virtual` should not be used to mark members that are inheritable and overridable. That concept is what is taught in schools, that concept is what is easily searchable, and that term is well known in the computer science field for this very concept. Just do a Google search between “open function” and “virtual function”. Deviating from this seems to be counter to one of Swift goals of being approachable. Having to learn `open` here is just mental noise that makes the coder have to think, “right… this is just a virtual method”.

To me, the better approach is:
change `open` to `virtual`
`virtual` is only allowed on inheritable and overridable members (i.e. `var`, `func`, and `subscript`)
`virtual` is not permitted on declarations that are explicitly `final` or `dynamic`. (Note that it's okay if one or both of the modifiers are implicitly inferred.)
A class is made inheritable outside of the module the **only** when the class is marked as both `public` and one or members are marked as `virtual` 

Lastly, it’s almost certainly a bug in your code if you mark a member as `open` on your public class but forget to annotate your class also with `open`. Worse, this error will **only** be caught if you attempt to use this type **outside** the context of tests because `@testable` will grant your module the `open` class state because `@testable` is special.

The only scenario that this change doesn’t allow would be the ability to subclass a class that has no virtual members. In my opinion, this scenario is better handled via extensions anyway.

However, **if** this scenario really was desirable, this could later be added by allowing `virtual` (or `inheritable` or `open`...) on a class definition. However, I would still make the argument that once you have a `virtual` member on a type, that the class is implicitly marked as `virtual` as well (see reasoning above).

Is the problem being addressed significant enough to warrant a change to Swift?
Yes

Does this proposal fit well with the feel and direction of Swift?
Yes

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
Yes, many. This proposal’s philosophical direction is more resilient by default.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
I’ve read the posts, thought about it, experimented, blogged about it.

-David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160721/bb501468/attachment.html>


More information about the swift-evolution mailing list