[pitch] @protected Attribute

According to the documentation, Swift access control modifies (open, public, internal, fileprivate, and private) restrict access to parts of your code from code in other source files and modules. That has been overwhelming reason why there is no protected access modifier such as in other languages.

In other programming languages, the protected access control modifier is for subclassing purposes. The protected modifier does not provide any specific protection because a subclass could provide a public method that directly calls the private method, thus the restriction is only a suggestion. Therefore, the main value of the protected keyword is that it provides a compiler check and suggestion to the user that the method is not intended for use outside subclasses.

That same value could be added without modifying the existing access control modifiers through an attribute on the method. The compiler, static analysis tools, and documentation generation tools would recognize this attribute and be able to generate a warning to the user if the method is used inappropriately.

To most closely resemble behavior developers are familiar with, it seems fitting for the attribute to be @protected. It could be applied to either 'internal,public, oropen` methods. Ideally, if a subclass overrides that method, the method override would inherit the attribute as well.

Possible Usage:

public class Foo {
    public var value: Int = 0 { 
        didSet { 
            didChangeValue() // No Warning
        }
    }
    @protected public func didChangeValue() { .... }
}
public class Bar: Foo {
    public func didChangeValue() { .... }
}
public Baz {
    func main() {
        let foo = Foo()
        foo.didChangeValue() // Generates a warning
    }
}

There has been a lot of discussion about the access control system, did you read some of it in the archive? If not, I suggest that you do – as far as I understand, the access control system is very unlikely to be changed.

4 Likes

I have read several previous discussions on the topic and I am in general agreement: There should not be any changes to the access control system. That’s why this is an attribute to provide a hint to the user at compile time.

I think either way you implement that, it would still add to the user understanding overhead on the permissions system.

I suspect a lot of the reason for fighting access control change isn’t centred around technical capabilities, but on making the access control system easy to understand. This would not help that, it would just mean it is a warning rather than an error.

I think protected is a great idea, but I share the Core Team’s concern about keeping the access control model simple and easy to use.

user understanding overhead

I think that phrase is important, but it should must be balanced against the features that reduce and minimize errors. Nullability is one such case already in the language. The concept and its applications may be non-obvious to new Swift developers, but it eliminates one of the most common source of errors when used properly.

More generically, additions to catch design/logic errors at compile time, without adding clutter to the code, provide a massive benefit to users of the language. An attribute like @protected should be part of a larger discussion about function restriction attributes. Without going into a deep dive on the topic, there would be several attributes that would catch common errors. Off the top of my head, I would imagine @requireCallSuper, @cannotCallSuper, and @mustOverride (for abstract method support), however I’m sure there would be others once the topic is opened.

1 Like

I agree with the basic premise that protected is not really access control, at least in the way access control manifests in Swift. If we were going to support something like this in Swift, this is the correct design for it, as an orthogonal attribute. This is in line with previous discussions about protected on the list.

5 Likes