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 or private[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] .