Swift Proposal: protected

There has been much said about protected and how Swift needs, I mean, NEEDS, the "protected" keyword. In fact, there has been so much ruckus about it that the Swift team wrote a blog entry on it: Access Control and protected.

While I whole heartedly agree that the protected keyword is a terrible idea from an inheritance perspective, the intent of the notion has great value. I'm going to define the intent as this:

The ability to separate concerns of implementors and consumers.

: .callout

If we focus the definition, it's really not that hard to image how we can extend the existing public, internal, and private access modifiers that Swift already offers with a fourth option: protected.

I propose that we could enable the following:

  1. Introduce the protected keyword
  2. Modify the import rules to include a protected modifier

The rule for the protected keyword would be quite simple:

Protected access enables entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module with the protected modifier. You typically use protected access to specify the public interface for those wishing to extend the functionality of your types, but hiding that functionality from the consumers of your API.

: .callout

An example would be this:

Defined in module FooMod

public struct Foo {
    public func foo() {}
    protected func bar() {}

    public var fizzy: Int
    protected var fuzzy: Int

protected func MakeSuperFoo() -\> Foo {}

Then, in another module, you would have to use the following in order to gain access to the protected members.

import FooMod                  // Brings in all of the public members
import protected FooMod        // Brings in all of the protected members

let f: Foo = MakeSuperFoo()

I think this fits into the existing access control mechanism perfectly and provides a way to provide the high-level intent of what people are asking for with protected.

Swift Proposal: protected