[swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

Matthew Johnson matthew at anandabits.com
Wed Jul 6 18:34:59 CDT 2016


> On Jul 6, 2016, at 5:13 PM, Scott James Remnant <scott at netsplit.com> wrote:
> 
> 
>> On Jul 6, 2016, at 2:47 PM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
>> 
>> This is not true.  Public classes will *not* be “final by default”.  It *will* be possible to subclass them within their declaring module.  If they need to be final they will still need to be marked as such.  
>> 
>> With that in mind, the your “can override” column (do you really mean “can subclass” here?) is also not correct.  The correct answer is “yes, within the module”.  The fundamental difference for this row is that there are some scopes which can *see* the type without the ability to subclass it.  There is no problem with this, it is *exactly* what we want.  
> 
> So would this be more accurate?
> 
>   access      | can access    | can subclass/  | final
>               |               | override where |
>  -------------+---------------+----------------+-------
>   open        | all scopes    | all scopes     | Error
>   public      | all scopes    | within module  | final
>   internal    | within module | within module  | final
>   fileprivate | within file   | within file    | final
>   private     | within scope  | within scope   | final

If you want to view “open” as an access modifier, then yes.

> 
>> The purpose of this proposal is precisely to give library authors the ability to have more fine grained control over what capabilities their library exposes to users.
>> 
> 
> I don’t have an issue with the purpose, I have an issue with doing it by conflating access control and finality, and making the language confusing as a result.

It’s not conflating access control and finality.

It is also possible to view “open” and “sealed" as part of an “inheritability" hierarchy rather than the access control hierarchy. 

final                    - never subclassable / overridable
sealed (default)  - subclassable / overridable *within* the declaring module
open                   - always subclassable / overridable

In some sense, “open” intersects access control and inheritability:  it only makes sense on a public declarations and therefore implies public (whether we allow public to be inferred or not).

> 
> Assuming the above table matches your expectation, compare it with the same matrix for the language as it is today:
> 
>   access      | can access    | can subclass/  | final
>               |               | override where |
>  -------------+---------------+----------------+-------
>   public      | all scopes    | all scopes     | final
>   internal    | within module | within module  | final
>   fileprivate | within file   | within file    | final
>   private     | within scope  | within scope   | final
> 
> The existing table is clean, it’s easy to understand; the two concepts are entirely separate from each other. The access control keyword defines where a class, method, property, or subscript can be accessed from; the `final` keyword defines whether or not it can be subclassed or overridden.

Many of us believe “final” is too blunt a tool.  There are many cases where final cannot be used but you still don’t want external users subclassing or overriding.  

We would like a more precise tool for these circumstances and believe if it is going to exist in Swift it should be the default.  Its behavior follows the principle of requiring programmers to explicitly make decisions about what behavior is exposed outside of a module.  You may not like that principle, but it is one that has been embraced by the language.

> 
> 
> To give you an example of the confusion, here is code made perfectly legal by SE-0025:
> 
>   public final class Example {
> 
>     overridable func foo() {}
> 
>   }

I have no idea how you think this is related to SE-0025 (scoped access control).  I also don’t understand why you think an `overridable` method in a `final` class would be legal under any proposal.  That is nonsense and clearly in error.

-Matthew

> 
> Scott

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160706/47053e7c/attachment.html>


More information about the swift-evolution mailing list