Why can't Swift protocols have private properties, and could Swift support access control within protocols? (protocols different roles)

Tangential to the main discussion points of this thread, but there is one application of private protocol members I've wished for in practice that the language doesn't currently have an excellent solution for: default implementations of protocol requirements.

Take a hypothetical example:

/// Conforming types keep a tally of some type of event.
protocol Tallying {
    var totalTally: Int { get }

    /// Records that the associated event has occurred by incrementing `totalTally`.
    mutating func tally()
}

In this case, the implementation of tally() is trivial and uninteresting, so it'd be great to give it a default implementation:

extension Tallying {
    mutating func tally() {
        totalTally += 1 // ❌ error: left side of mutating operator isn't mutable: 'totalTally' is a get-only property
    }
}

Ideally, it'd be great to be able to express

protocol Tallying {
    var totalTally: Int { get private(set) }
}

but this isn't currently allowed. At the moment, you have to:

  1. Declare totalTally's setter as public,
  2. Keep totalTally as-is, but give it a default implementation in terms of, e.g., a property like _totalTally (public, but underscored to discourage direct use), or
  3. Turn Tallying into a class with a private setter for totalTally and an implementation of tally(), from which other classes can inherit

(1) opens the door for accidental misuse of the property; (2) makes accidental misuse less likely, but makes conforming to the protocol convoluted (especially if the protocol has a long list of requirements); (3) is only applicable for classes (which don't already need to inherit from a different existing type).

(I completely agree with Swift's take that a protocol should define the public, semantic interface of a type — but to some extent, you can argue that "this property must be internally mutable since the semantics of the protocol require it to change" could be included in that approach.)

8 Likes