Looking at some scala-docs of my libraries, it appeared to me that there is some unwanted noise from value classes. For example:
implicit class RichInt(val i: In
Perhaps the problem is the heterogeneous scenarios for which value classes were plotted. From the SIP:
• Inlined implicit wrappers. Methods on those wrappers would be translated to extension methods.
• New numeric classes, such as unsigned ints. There would no longer need to be a boxing overhead for such classes. So this is similar to value classes in .NET.
• Classes representing units of measure. Again, no boxing overhead would be incurred for these classes.
I think there is a difference between the first and the last two. In the first case, the value class itself should be transparent. You wouldn't expect anywhere a type RichInt
, but you only really operate on Int
. In the second case, e.g. 4.meters
, I understand that getting the actual "value" makes sense, hence requiring a val
is ok.
This split is again reflected in the definition of a value class:
1. C must have exactly one parameter, which is marked with val and which has public accessibility.
...
7. C must be ephemeral.
The latter meaning it has no other fields etc., contradicting No. 1.
With
class C(val u: U) extends AnyVal
the only ever place in the SIP where u
is used, is in example implementations (e.g. def extension$plus($this: Meter, other: Meter) = new Meter($this.underlying + other.underlying)
); and then in intermediate representations, only to be erased again finally:
new C(e).u ⇒ e
The intermediate representation being accessible for synthetic methods IMO is something that could also be done by the compiler, but should not be visible in the user written code. (I.e., you can use a val
if you want to access the peer, but don't have to).