As specified:
A method named copy
is implicitly added to every case class, unless the class already has a member with that name, whether directly defined or inherited. The copy
method is also omitted if the class is abstract, or if the class has a repeated parameter.
There is an old ticket where the issue seems to have crossed with whether copy supports case classes with multiple parameter lists.
I assume the reason is that you would have to awkwardly supply a Seq
.
Inside a method, a repeating parameter is a Seq
, but this detail is not visible outside, except in the signature of unapplySeq
, or when a method is eta-expanded.
I don’t know whether that is an excellent reason.
A similar feature restriction that was relaxed in Scala 3 is by-name repeated parameters:
scala> def f(i: => Int*) = i.sum
def f(i: => Int*): Int
I guess that is a by-name Seq
and not a Seq
of by-names (functions). That detail is probably why it was not implemented for so long.
For copy
, would it replace all the repeated args? (Probably)
k.copy(i = 42)
But Scala 3 is experimenting with creative use of braces (now that code is braceless), so maybe the syntax could be
k.copy(i = { 42, 27 })
or brackets, I meant brackets
k.copy(i = [ 42, 27 ])
Or, since Scala 3 aims for simplicity, it’s simpler to disallow it.
Additionally, it was a year ago this month that Scala 2 got copy with by-name parameters in the signature (under -Xsource:3-cross
):
Welcome to Scala 2.13.16 -Xsource:3.0.0 (OpenJDK 64-Bit Server VM, Java 23.0.2).
Type in expressions for evaluation. Or try :help.
scala> case class C(i: Int)(j: => Int) { def total = i + j }
class C
scala> val c = C(42)(27)
val c: C = C(42)
scala> c.copy()(j = 1).total
val res0: Int = 43