This is a proposal to retain
private[this] in Scala 3.
This proposal based on this discussion.
This proposal is not based on an ideological desire to reduce the number of changes between Scala 2 and 3. (Although we will happily accept support from this camp ).
This proposal is motivated by the fact that
private[this] is a very useful design tool.
private[this] is a mechanism to designate a variable as a secret within an object instance. When we use
private[this], future developers are prevented from using the variable in a non-secret context. There’s a mechanical connection between our use of
private[this] and the future developers, ie. they will encounter a compile error if they attempt to use the secret variable outside of the object instance. This mechanical connection is what makes
This mechanism has a valuable second-order effect: future programmers can observe that the original designer intended for the variable to be a secret. (This is an instance of what MIT’s Jimmy Koppel calls the Embedded Design Principle.)
Scala’s concept of companion objects makes
private[this] even more useful than it might otherwise be:
For example, in Java a variable marked
private can still be accessed by another instance of that type. afaik there’s no way to mark a variable as a secret to be accessed only within its object instance. Java is missing this tool.
If Scala 3 omits
private[this] it will be missing this tool like Java. However, since Scala has companion objects, this omission seems more egregious because the gap between the set of potential accessors of a variable under
private is larger due to the use of private variables in companion objects. Ie., in Java a
private variable might be used in its own instance or another instance of its type. Scala extends this set with potential access in the companion object.
So – this proposal asks that Scala 3 retain the ability to mark a variable as usable only within an object instance and not other instances of its type or companion. This is a very useful thing.
Martin remarks on the reasoning to remove
- it is syntactically an irregular case. A pair of brackets usually encloses a type, but
thisis a value.
- it leads to bike shedding: should I use
private[this]? One is shorter but the other might be more efficient.
- its effect over
privateis purely local and can be easily inferred
Responding to each point –
(1) this proposal does not consider syntax. Personally I think the syntax is satisfactory. The syntax may be technically irregular but it’s visibly similar to access qualifiers like
private[MyObject], a feature which I believe is retained in Scala 3.
(2) this proposal agrees that any efficiency of
private may be subject to bike shedding. However this proposal argues for the value of
private[this] as a design tool. Its use from this standpoint is not at all bike shedding.
(3) discussions of efficiency and inference are orthogonal to the value of
private[this] as a design tool. Inference is done at compile time, after the code has been written. So the inference has nothing to do with
private[this] being a mechanism for the programmer to express the design intention of the variable being a secret within a class. That’s why dropping
private[this] is a loss to the language.
We have argued that
private[this] is a valuable design tool, orthogonal to concerns of inference or efficiency. We hope that Scala 3 retains
As a philosophical note, I feel that
private[this] is an exemplar of a kind of rich ability to embed one’s design intent within the code that is a hallmark of Scala. It helps make Scala special.