This is a proposal to retain private[this] in Scala 3.
This proposal based on this discussion.
The PR to remove private[this] from Scala 3 is here. Some of the threads that lead to the current removal of private[this] from Scala 3 are here and here.
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 private[this] useful.
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[this] vs 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 private[this]:
- 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
privateorprivate[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[this] vs 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.
In conclusion,
We have argued that private[this] is a valuable design tool, orthogonal to concerns of inference or efficiency. We hope that Scala 3 retains private[this].
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.