Option to generate `class` instead of `case class`
armanbilge opened this issue · 1 comments
Motivation:
- we'd like to build client libraries based on ScalaPB-generated code that make a best effort to preserve binary-compatibility.
case class
es are notoriously bad for binary-compatible evolution, as documented in this Scala Contributors thread:
https://contributors.scala-lang.org/t/pre-sip-structural-data-structures-that-can-evolve-in-a-binary-compatible-way/5684
The proposal is to add an option that generates ordinary class
es with a private
constructor, instead of case class
es. In addition, this option would have to:
- prefix fields with
val
. Actually, this is okay to do forcase class
es as well. - override
equals
,hashCode
, andtoString
methods, to matchcase class
behavior (as demonstrated in the Contributors thread) - generate a
private def copy(...)
method - use
new
instead ofapply
(actually this could be a general performance optimization) and/or generate aprivate def apply(...)
method - add a no-args public
def apply()
method - remove or make private the
of
method
There would be no public replacements for apply(...)
, of
, unapply
, or copy
, because it is difficult/impossible for generated code to evolve these methods binary-compatibly.
I think that is roughly all the changes that would be needed. Thoughts? Thanks in advance!
Hi @armanbilge , thanks for putting in the proposal. I have actually implemented this three years ago (still in the classes
branch) and the reason for it not to get merged is discussed here: #778 (comment)
In short, it's complexity and maintainability vs value. Since this rarely comes up as a problem in practice, I'm not inclined to make this change.