Why is there a restriction on refinements not having vars?

{var a: Int} is currently blocked in Scala 3.3.1, and I can’t for the life of me understand why. The error message says that I can manually define {def a: Int; def a_=(value: Int): Unit}, but why do I have to write all that out? Why can’t the former automatically be assumed to be the latter?

1 Like

It simplifies the language if we don’t have to add that case. In the rare occurrences where it is needed, it should be acceptable to just write the getter and setter.

1 Like

You mean it simplifies the implementation? :wink:


The reason I ask, is I’m trying to generate implementation of these refinements that a user is asking for. For example, in the best case a user would pass in Struct{ var a: Int } and I would create an instance of that type that suits their needs while hiding the implementation. Them having to write Struct{ def a: Int; def a_=(value: Int): Unit} is a great deal more error prone on the usability side, requires I check that getters and setters align properly, and more than doubles the work for something that would be fairly common for this datatype. The alternative, writing a wrapper datatype such as Struct{ val a: Field[Int] } also requires extra checks on the refinements the user sends in and just adds extra noise to the definition for no real gain imo.

If creating these refinements from type data was possible, I could write a nicer api that would work, but that’s not the case right now.


No, it does not make the language simpler, it makes it harder, for now one has to remember this exception to the (assumed) rule*. What is true, is that this seems a rare construction, I never needed something like this myself either, but that does not change the fact itself, imho.

(* This happens more often in Scala, that something is forbidden you would expect to work, even for good reason, but also then it makes the language less orthogonal. A simple language does not only contain a limited amount of keywords, but also as few as possible exceptions to its generic syntax rules as reasonably possible.)


OK, I think it’s no big deal either way, but since it is in Scala 2, the path of least resistance is to put it in Scala 3 as well. See Allow `var` in refinements · Issue #19809 · lampepfl/dotty · GitHub.