This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Abstract base class, case classes and copy once again

21 replies
pkolaczk
Joined: 2010-01-14,
User offline. Last seen 2 years 38 weeks ago.

Hi,

I know it was once questioned on the list, but the answer "it can't be
done" does not satisfy me.

My problem is slightly more specific, so I still have some hope.

There are many case classes sharing some common property:

trait HasId {
def id: String
}

case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId
case class CC2(id: String, a2: A2, b2: B2, ...) extends HasId
case class CC3(id: String, a3: A3, b3: B3, ...) extends HasId
...
case class CCn(id: String, an: AN, bn: BN, ...) extends HasId

Now I want to implement a copy method in HasId that copies the object
giving it a different Id:

trait HasId {
def id: String

def withDifferentId(newId: String): HasId = {
// what to put here?
}
}

Constraints:
Because n is quite large, I want to restrict the modifications as much
as possible to modifications that could be achieved with automatic
refactoring tools, or better, by just modifying the common base class,
not the case classes. There is code outside already using those case
classes, so their interface should not change.

For example this obvious solution:

trait HasId {
def id: String
def withDifferentId(newId: String): HasId
}

case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId {
def withDifferentId(newId: String) = copy(id = newId)
}

is not acceptable. Also copying the same line n times violates DRY.

So, is it possible with Scala to solve it in an elegant way? The code
need not be fast, it can use reflection, structural types, etc.

Regards,
Piotr

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Abstract base class, case classes and copy once again

solution one:
class IdCC[CC](val cc:CC, val id:Int) {def withNewId(i:Int) = obivious()}

solution two, if you insist on not using a wrapper:
object MailingListRiddle {
trait HasId extends Cloneable {
private var secretId = 0;
def id = secretId

def withNewId(newId: Int) = {
val clone = super.clone().asInstanceOf[HasId]
clone.secretId = newId
clone
}
override def clone() = super.clone().asInstanceOf[HasId]
}

case class A(str: String) extends HasId

def main(args: Array[String]) {
val a = A("clone me")
val modifiedCopy = a.withNewId(5)
println(modifiedCopy.id)
}
}

if you cannot implement cloneable, there are libraries which can clone
everything via reflection. it's also possible to change the value of
final fields via reflection if a var is not an option.
as a last resort, you can also create a proxy at runtime using cglib
(google it, it's pretty nice for metaprogramming) and intercept all
calls to the id-method

always remember: it's only unpure if someone catches you doing it :)

Am 17.01.2012 21:36, schrieb Piotr Kołaczkowski:
> Hi,
>
> I know it was once questioned on the list, but the answer "it can't be
> done" does not satisfy me.
>
> My problem is slightly more specific, so I still have some hope.
>
> There are many case classes sharing some common property:
>
> trait HasId {
> def id: String
> }
>
> case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId
> case class CC2(id: String, a2: A2, b2: B2, ...) extends HasId
> case class CC3(id: String, a3: A3, b3: B3, ...) extends HasId
> ...
> case class CCn(id: String, an: AN, bn: BN, ...) extends HasId
>
>
> Now I want to implement a copy method in HasId that copies the object
> giving it a different Id:
>
> trait HasId {
> def id: String
>
> def withDifferentId(newId: String): HasId = {
> // what to put here?
> }
> }
>
> Constraints:
> Because n is quite large, I want to restrict the modifications as much
> as possible to modifications that could be achieved with automatic
> refactoring tools, or better, by just modifying the common base class,
> not the case classes. There is code outside already using those case
> classes, so their interface should not change.
>
> For example this obvious solution:
>
> trait HasId {
> def id: String
> def withDifferentId(newId: String): HasId
> }
>
> case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId {
> def withDifferentId(newId: String) = copy(id = newId)
> }
>
> is not acceptable. Also copying the same line n times violates DRY.
>
> So, is it possible with Scala to solve it in an elegant way? The code
> need not be fast, it can use reflection, structural types, etc.
>
> Regards,
> Piotr
>
>

MattRussell
Joined: 2009-07-22,
User offline. Last seen 45 weeks 3 days ago.
Re: Abstract base class, case classes and copy once again
I asked about this on SO last week; I don't think there is a nice solution at this point:
  http://stackoverflow.com/questions/8801818/polymorphic-updates-in-an-immutable-class-hierarchy
In a way it's a shame that it's just the single copy method that's generated for case classes, rather than (or as well as) a bunch of "withXXX" methods for each field. Maybe this is something that could be achieved with Scala Macros (http://scalamacros.org/) or a compiler plug-in? 
-- Matt
pkolaczk
Joined: 2010-01-14,
User offline. Last seen 2 years 38 weeks ago.
Re: Abstract base class, case classes and copy once again

W dniu 18.01.2012 10:08, Matt Russell pisze:
> I asked about this on SO last week; I don't think there is a nice
> solution at this point:
>
> http://stackoverflow.com/questions/8801818/polymorphic-updates-in-an-imm...
>
> In a way it's a shame that it's just the single copy method that's
> generated for case classes, rather than (or as well as) a bunch of
> "withXXX" methods for each field. Maybe this is something that could be
> achieved with Scala Macros (http://scalamacros.org/) or a compiler plug-in?
>

Rüdiger Klaehn
Joined: 2009-06-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Abstract base class, case classes and copy once again

On 17 Jan., 22:08, HamsterofDeath wrote:
>
> solution one:
> class IdCC[CC](val cc:CC, val id:Int) {def withNewId(i:Int) = obivious()}
>
Maybe I'm dense, but does that help? What is the obivious solution?

> solution two, if you insist on not using a wrapper:
> object MailingListRiddle {
>     trait HasId extends Cloneable {
>         private var secretId = 0;
>         def id = secretId
>
>         def withNewId(newId: Int) = {
>             val clone = super.clone().asInstanceOf[HasId]
>             clone.secretId = newId
>             clone
>         }
>         override def clone() = super.clone().asInstanceOf[HasId]
>     }
>
>     case class A(str: String) extends HasId
>
>     def main(args: Array[String]) {
>         val a = A("clone me")
>         val modifiedCopy = a.withNewId(5)
>         println(modifiedCopy.id)
>     }
>
> }
>
> if you cannot implement cloneable, there are libraries which can clone
> everything via reflection. it's also possible to change the value of
> final fields via reflection if a var is not an option.
> as a last resort, you can also create a proxy at runtime using cglib
> (google it, it's pretty nice for metaprogramming) and intercept all
> calls to the id-method
>
> always remember: it's only unpure if someone catches you doing it :)
>
What if the case class contains (lazy) vals that depend on the
constructor parameters. As soon as you have that you will be screwed
if you use clone or some other method to update just the one field,
since the lazy val will not be updated.

case class Bla(a:Int, b:Int) extends HasA {
lazy val sum = a + b
}

Now if you have a Bla with a=1 and b=2, and you change a to 2 using
some hack, the lazy val will have the wrong value. And this will be
hard to find since if you create the class using the constructor,
everything is OK.

Also, forget about all require(...) or other initialization code you
have in your class, since they will not be evaluated by the clone/
private var method. The only situation where the clone/private var
method makes sense is when all fields are completely independent of
each other.

pkolaczk
Joined: 2010-01-14,
User offline. Last seen 2 years 38 weeks ago.
Re: Abstract base class, case classes and copy once again

W dniu 18.01.2012 14:35, rklaehn pisze:
> On 17 Jan., 22:08, HamsterofDeath wrote:
>>
>> solution one:
>> class IdCC[CC](val cc:CC, val id:Int) {def withNewId(i:Int) = obivious()}

>>
> Maybe I'm dense, but does that help? What is the obivious solution?

def withNewId(i: Int) = new IdCC(cc, i)

But that of course does not satisfy me because of two reasons:
1. CC may be sometimes dependent on id in my code
2. This would require changing lots of code.

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Abstract base class, case classes and copy once again

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

You want asymmetric lenses.

On 01/18/2012 06:36 AM, Piotr Kołaczkowski wrote:
> Hi,
>
> I know it was once questioned on the list, but the answer "it can't be
> done" does not satisfy me.
>
> My problem is slightly more specific, so I still have some hope.
>
> There are many case classes sharing some common property:
>
> trait HasId {
> def id: String
> }
>
> case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId
> case class CC2(id: String, a2: A2, b2: B2, ...) extends HasId
> case class CC3(id: String, a3: A3, b3: B3, ...) extends HasId
> ...
> case class CCn(id: String, an: AN, bn: BN, ...) extends HasId
>
>
> Now I want to implement a copy method in HasId that copies the object
> giving it a different Id:
>
> trait HasId {
> def id: String
>
> def withDifferentId(newId: String): HasId = {
> // what to put here?
> }
> }
>
> Constraints:
> Because n is quite large, I want to restrict the modifications as much
> as possible to modifications that could be achieved with automatic
> refactoring tools, or better, by just modifying the common base class,
> not the case classes. There is code outside already using those case
> classes, so their interface should not change.
>
> For example this obvious solution:
>
> trait HasId {
> def id: String
> def withDifferentId(newId: String): HasId
> }
>
> case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId {
> def withDifferentId(newId: String) = copy(id = newId)
> }
>
> is not acceptable. Also copying the same line n times violates DRY.
>
> So, is it possible with Scala to solve it in an elegant way? The code
> need not be fast, it can use reflection, structural types, etc.
>
> Regards,
> Piotr
>

Rüdiger Klaehn
Joined: 2009-06-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Abstract base class, case classes and copy once again
On Wed, Jan 18, 2012 at 10:08 AM, Matt Russell <mattrusselluk@gmail.com> wrote:
I asked about this on SO last week; I don't think there is a nice solution at this point:
  http://stackoverflow.com/questions/8801818/polymorphic-updates-in-an-immutable-class-hierarchy
In a way it's a shame that it's just the single copy method that's generated for case classes, rather than (or as well as) a bunch of "withXXX" methods for each field. Maybe this is something that could be achieved with Scala Macros (http://scalamacros.org/) or a compiler plug-in? 
Actually I think that this comes up so often that some kind of solution should be built in to the language. A case class generates a million invisible methods anyway, so why not implement an additional "modify with just this value changed" method for each constructor argument?
Maybe there is a better solution, but something has to be done about this.
Rüdiger Klaehn
Joined: 2009-06-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Abstract base class, case classes and copy once again
How would that work in detail in this case? 
You have two objects A and B that implement some trait HasID. Now you want to return a copy of an object implementing HasID without knowing if it is an A or a B. I understand how you modify the id once you have the lens, but how do you get the right lens from inside HasID? The only solution I can see would be to have a third method in HasID, and to implement this method in each concrete class A, B. But then you have lots of boilerplate code in the concrete classes again.
trait HasId {
 def id: String
 def withDifferentId(newId: String): HasId = {
   idLens.updated(this, newID)
 }
 def idLens : Lens[String]


On Wed, Jan 18, 2012 at 9:48 PM, Tony Morris <tonymorris@gmail.com> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

You want asymmetric lenses.

On 01/18/2012 06:36 AM, Piotr Kołaczkowski wrote:
> Hi,
>
> I know it was once questioned on the list, but the answer "it can't be
> done" does not satisfy me.
>
> My problem is slightly more specific, so I still have some hope.
>
> There are many case classes sharing some common property:
>
> trait HasId {
>   def id: String
> }
>
> case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId
> case class CC2(id: String, a2: A2, b2: B2, ...) extends HasId
> case class CC3(id: String, a3: A3, b3: B3, ...) extends HasId
> ...
> case class CCn(id: String, an: AN, bn: BN, ...) extends HasId
>
>
> Now I want to implement a copy method in HasId that copies the object
> giving it a different Id:
>
> trait HasId {
>   def id: String
>
>   def withDifferentId(newId: String): HasId = {
>      // what to put here?
>   }
> }
>
> Constraints:
> Because n is quite large, I want to restrict the modifications as much
> as possible to modifications that could be achieved with automatic
> refactoring tools, or better, by just modifying the common base class,
> not the case classes. There is code outside already using those case
> classes, so their interface should not change.
>
> For example this obvious solution:
>
> trait HasId {
>   def id: String
>   def withDifferentId(newId: String): HasId
> }
>
> case class CC1(id: String, a1: A1, b1: B1, ...) extends HasId {
>   def withDifferentId(newId: String) = copy(id = newId)
> }
>
> is not acceptable. Also copying the same line n times violates DRY.
>
> So, is it possible with Scala to solve it in an elegant way? The code
> need not be fast, it can use reflection, structural types, etc.
>
> Regards,
> Piotr
>


- --
Tony Morris
http://tmorris.net/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJPFzA2AAoJEPxHMY3rBz0Pc9AIAMsiRThCDArGspLaPg2IPQip
ebxkev8Pp2K7RxdU8/QHB+Tgp30fzW+UdiHpMdC+blNuSODpi+CT0iOzBzbRxCQp
KJjPM+sEcpVkVeUXbM9/MevpJ+MH2ySxZ6b4Y/wLcSMOpeyi+YhHmLBGcUyh/u+G
3FnwdfH1RlLHK67b1i0wTgLugeZsN4bSjORegCI0OPufsDJhBeqfeEOrRK6O/AJF
TH5qYZswpjCiv/j/lC7KQ/Df+lNkzqOubA0dDgy0VqjbgDeNTtEqYuLjDTp6zxHO
rsF21HSQxBKcVnImRBERghuU/Fppqy5R6umI+wF6gROGtuLDlQ5/WkCcig/9Wpw=
=2qGX
-----END PGP SIGNATURE-----

MattRussell
Joined: 2009-07-22,
User offline. Last seen 45 weeks 3 days ago.
Re: Re: Abstract base class, case classes and copy once again
On Friday, January 20, 2012 10:44:50 AM UTC, rklaehn wrote:
Actually I think that this comes up so often that some kind of solution should be built in to the language. A case class generates a million invisible methods anyway, so why not implement an additional "modify with just this value changed" method for each constructor argument?

What name would you choose for those methods?
-- Matt
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Re: Abstract base class, case classes and copy once again

case class (fooBar:String)

->
def withUpdatedFooBar(foobar:String = copy(...)

one update method per field

-------- Original-Nachricht --------
> Datum: Fri, 20 Jan 2012 04:43:47 -0800 (PST)
> Von: Matt Russell
> An: scala-user@googlegroups.com
> Betreff: Re: [scala-user] Re: Abstract base class, case classes and copy once again

> On Friday, January 20, 2012 10:44:50 AM UTC, rklaehn wrote:
> >
> > Actually I think that this comes up so often that some kind of solution
> > should be built in to the language. A case class generates a million
> > invisible methods anyway, so why not implement an additional "modify
> with
> > just this value changed" method for each constructor argument?
> >
>
> What name would you choose for those methods?
>

MattRussell
Joined: 2009-07-22,
User offline. Last seen 45 weeks 3 days ago.
Re: Re: Abstract base class, case classes and copy once again
On Friday, January 20, 2012 12:49:34 PM UTC, Dennis Haupt wrote:

def withUpdatedFooBar(foobar:String = copy(...)

Right, and that's what I'd call them if I wrote them by hand. Downside is that you'd have to do something special for symbolic field names, and it'd be a bit nasty for someone using non-English field names (although we already have @BeanProperty...).
-- Matt


H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Re: Abstract base class, case classes and copy once again

if there really is someone giving his case classes french names and fields, the compiler could still generate a setter like it does already for any other var - just that the implementation calls copy

that would be language neutral

-------- Original-Nachricht --------
> Datum: Fri, 20 Jan 2012 04:59:10 -0800 (PST)
> Von: Matt Russell
> An: scala-user@googlegroups.com
> Betreff: Re: [scala-user] Re: Abstract base class, case classes and copy once again

> On Friday, January 20, 2012 12:49:34 PM UTC, Dennis Haupt wrote:
>
> def withUpdatedFooBar(foobar:String = copy(...)
> >
> Right, and that's what I'd call them if I wrote them by hand. Downside is
> that you'd have to do something special for symbolic field names, and it'd
> be a bit nasty for someone using non-English field names (although we
> already have @BeanProperty...).
>

Stefan Zeiger
Joined: 2008-12-21,
User offline. Last seen 27 weeks 3 days ago.
Re: Re: Abstract base class, case classes and copy once again
On 2012-01-20 13:59, Matt Russell wrote:
On Friday, January 20, 2012 12:49:34 PM UTC, Dennis Haupt wrote:

def withUpdatedFooBar(foobar:String = copy(...)

Right, and that's what I'd call them if I wrote them by hand. Downside is that you'd have to do something special for symbolic field names, and it'd be a bit nasty for someone using non-English field names (although we already have @BeanProperty...).

Unfortunately, assignment in Scala always returns Unit, even if it calls a _= method, so it's useless for updating immutable values. Otherwise you could do

case class Foo(bar: Int) { def bar_=(bar: Int) = copy(bar = bar) }

val a = new Foo(1)
val b = a.bar = 42

--sz
MattRussell
Joined: 2009-07-22,
User offline. Last seen 45 weeks 3 days ago.
Re: Re: Abstract base class, case classes and copy once again
On Friday, January 20, 2012 1:07:05 PM UTC, HamsterofDeath wrote:
if there really is someone giving his case classes french names and fields, the compiler could still generate a setter like it does already for any other var - just that the implementation calls copy

that would be language neutral

So, you could write, e.g.
  val newPerson = (person.age = person.age + 1) 
The trouble is it's much harder to distinguish regular assignment from an update in that scenario. (Also, I couldn't get that particular assignment sugar to work with case classes as they stand right now -- because the getters are vals?).
-- Matt
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Re: Abstract base class, case classes and copy once again

this is no holy law. it could be changed for case classes

-------- Original-Nachricht --------
> Datum: Fri, 20 Jan 2012 14:23:43 +0100
> Von: Stefan Zeiger
> An: scala-user@googlegroups.com
> Betreff: Re: [scala-user] Re: Abstract base class, case classes and copy once again

> On 2012-01-20 13:59, Matt Russell wrote:
> > On Friday, January 20, 2012 12:49:34 PM UTC, Dennis Haupt wrote:
> >
> > def withUpdatedFooBar(foobar:String = copy(...)
> >
> > Right, and that's what I'd call them if I wrote them by hand. Downside
> > is that you'd have to do something special for symbolic field names,
> > and it'd be a bit nasty for someone using non-English field names
> > (although we already have @BeanProperty...).
> >
>
> Unfortunately, assignment in Scala always returns Unit, even if it calls
> a _= method, so it's useless for updating immutable values. Otherwise
> you could do
>
> case class Foo(bar: Int) { def bar_=(bar: Int) = copy(bar = bar) }
>
> val a = new Foo(1)
> val b = a.bar = 42
>
> --sz

MattRussell
Joined: 2009-07-22,
User offline. Last seen 45 weeks 3 days ago.
Re: Re: Abstract base class, case classes and copy once again
On Friday, January 20, 2012 1:23:43 PM UTC, Stefan Zeiger wrote:
Unfortunately, assignment in Scala always returns Unit, even if it calls a _= method

I don't think that's the case:
scala> class Person(_age: Int) { def age = _age; def age_=(x: Int)= new Person(x) ; override def toString = "Person(" + age + ")" }
defined class Person
scala> val p = new Person(30)p: Person = Person(30)
scala> val p2 = (p.age = p.age + 1)p2: Person = Person(31)
-- Matt
Stefan Zeiger
Joined: 2008-12-21,
User offline. Last seen 27 weeks 3 days ago.
Re: Re: Abstract base class, case classes and copy once again
On 2012-01-20 14:32, Matt Russell wrote:
On Friday, January 20, 2012 1:23:43 PM UTC, Stefan Zeiger wrote:
Unfortunately, assignment in Scala always returns Unit, even if it calls a _= method

I don't think that's the case:
scala> class Person(_age: Int) { def age = _age; def age_=(x: Int)= new Person(x) ; override def toString = "Person(" + age + ")" }

You're right, this works indeed. I thought I had just tried the same thing but in all versions I had small differences. Still, it doesn't work if age is a val instead of a def. That just results in a "reassignment to val" error.

--sz
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Re: Abstract base class, case classes and copy once again

i can see a clear difference between
val x = (x.foo = "100")
and
x.foo = 100

in case you forget to use the result, the compiler should refuse to compile since it's clearly an error.

-------- Original-Nachricht --------
> Datum: Fri, 20 Jan 2012 05:28:12 -0800 (PST)
> Von: Matt Russell
> An: scala-user@googlegroups.com
> Betreff: Re: [scala-user] Re: Abstract base class, case classes and copy once again

> On Friday, January 20, 2012 1:07:05 PM UTC, HamsterofDeath wrote:
> >
> > if there really is someone giving his case classes french names and
> > fields, the compiler could still generate a setter like it does already
> for
> > any other var - just that the implementation calls copy
> >
> > that would be language neutral
> >
> So, you could write, e.g.
>
> val newPerson = (person.age = person.age + 1)
>
> The trouble is it's much harder to distinguish regular assignment from an
> update in that scenario. (Also, I couldn't get that particular assignment
> sugar to work with case classes as they stand right now -- because the
> getters are vals?).
>

Rüdiger Klaehn
Joined: 2009-06-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Abstract base class, case classes and copy once again
I suffer from this quite a lot in my current project. My convention is withX for a method that changes x on an immutable object and does everything else to get back a consistent object (change other fields), and justX for a method that changes just the field x and leaves every other field the same. 
Usually I make justX protected since it might result in an inconsistent state. So all my concrete classes look like e.g.:
trait HasID {  type Self
  def id:Int
  def withId(value:Int) =   if(this.id==value) this else justId(value)
  protected def justId(id:Int) : Self}

case class Fnord(id:Int, name:String) extends HasID {      protected def justId(value:Int) = copy(id=value)
  protected def justName(value:String) = copy(name=value) }
Writing all those just... methods is extremly annoying, but at least you can always copy and paste them. The logic to check if a new copy is actually required is in the public withXXX method.

On Fri, Jan 20, 2012 at 1:43 PM, Matt Russell <mattrusselluk@gmail.com> wrote:
On Friday, January 20, 2012 10:44:50 AM UTC, rklaehn wrote:
Actually I think that this comes up so often that some kind of solution should be built in to the language. A case class generates a million invisible methods anyway, so why not implement an additional "modify with just this value changed" method for each constructor argument?

What name would you choose for those methods?
-- Matt

Andreas Scheinert
Joined: 2011-02-11,
User offline. Last seen 42 years 45 weeks ago.
Re: Abstract base class, case classes and copy once again

Hi!
Do these semantics appeal to you?
https://github.com/gseitz/Lensed

Regards Andreas

On Jan 18, 6:44 pm, Piotr Kołaczkowski
wrote:
> W dniu 18.01.2012 14:35, rklaehn pisze:
>
> > On 17 Jan., 22:08, HamsterofDeath  wrote:
> >>
> >> solution one:
> >> class IdCC[CC](val cc:CC, val id:Int) {def withNewId(i:Int) = obivious()}
>
> > Maybe I'm dense, but does that help? What is the obivious solution?
>
> def withNewId(i: Int) = new IdCC(cc, i)
>
> But that of course does not satisfy me because of two reasons:
> 1. CC may be sometimes dependent on id in my code
> 2. This would require changing lots of code.
>

Michael Thaler 2
Joined: 2011-12-25,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Abstract base class, case classes and copy once again
In addition to the points already mentioned, having withX methods on case classes to update fields would be very useful for interoperability with Java where the copy method provided by the case classes is useless because you have to specify all arguments.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland