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
this
is a value.- it leads to bike shedding: should I use
private
orprivate[this]
? One is shorter but the other might be more efficient.- its effect over
private
is 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.