I recently found myself writing a lot of case class definitions like this
case class A(x: Int, a: A)
case class B(x: Int, b: B)
case class C(x: Int, c: C)
So they have common part and custom part. Right now, AFAIK, we don’t have the mechanism that would allow us to share parts of a case class. In a perfect world, I would be able to write
case class Base(x: Int)
case class A(a: A) extends2 Base
case class B(b: B) extends2 Base
case class C(c: C) extends2 Base
and then leverage all the benefits of case classes, so valid toString, equals, hashcode and all the libs with special macro treatment for them.
Of course, extend cannot be used for that purpose, but we could probably come up with a new keyword.
The tricky part is instantiation, where in this case we have a constructor with 1 visible parameter but we need to provide 2. One solution would be the desugaring that will provide an artificial constructor which would be the concatenation of all the extended case classes, so it looks like
val x = C(???, 1)
But this sounds a little bit complex and may be hard to understand and hard for tooling to support.
This also reminds trait parameters a bit, but the drawback of those is that you have to repeat all the parameters in the final class constructor so you can pass them down (if I remember and understand them correctly).
Second thing is that I’m not sure if macros (like one for deriving json codecs) would be able to work with trait parameters, and this is one of the most important parts.
I realized that what I really want is a support of proper records, where order of fields doesn’t matter, available e.g. in typescrit. And such behavior would be part of it. Whatever we do with case classes is rather poor imitation.
You can just create traits, then instantiate them via Factory in feature.scala. The memory layout of the created objects are more compact than shapeless’ HList based records.
This implementation adds full features records to dotty. I have no idea if authors are reading this forum or if they are in contact with EPFL but it would be really nice to have this extension in dotty.
There is also some older threads/discussions here:
And I have looked at
shapeless records and scala-records but neither of them is adopted or highly usable (you can see why in the first presentation, which also compares them).