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

Scala 2.8 best practices about clone / copy constructor / factory / etc ?

25 replies
fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.

Hello,

I'm in the process of building a my domain model and I'm wondering what
are the Scala best practices regarding the cloning subject for
inheritance hierarchy.

A typical example of hierarchy could be:

==========================
class Person(val name : String) {
var address : Adress
}

class Child(val father : Person, val mother : Person) {
val brothers = Buffer[Person]()
}

trait HasPassword {
var pwd : String
}

class User(val login : String) extends User with HasPassword {
...
}
==========================

It is of course just an example of the different use cases that I
encountered, and maybe there are a lots of other than just class and/or
trait with val and/or vars and/or (im)mutable collections.

So, what are the best practices to minimize code duplication and be able
to make deep copies of objects ?

Case with only vals (immutable state in general) are rather simple, but
there are all the others...

I saw somewhere that 2.8 named/defaults arguments may bring some great
enhancement in this area, but I can't find any resources about that anymore.

Thanks in advance for all the good advice you scalazies will give !

--
Francois Armand

Sebastien Bocq
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
Hi,

I'm struggling with this too. Is there any cloning support in 2.8 like found in some prototype-based languages?

Maybe 'clone' could be a keyword used like this:

trait Person {
  val name:String 
  val other = "XXX"
}

trait Question  {
  val q:String
}

val fanf = new Person with Question {val name="fanf"; val q="What about clone?"}

val seb = clone fanf {val name="seb"}

Any suggestion?

Thanks,
Sebastien

2009/10/23 Francois <fanf42@gmail.com>
Hello,

I'm in the process of building a my domain model and I'm wondering what are the Scala best practices regarding the cloning subject for inheritance hierarchy.

A typical example of hierarchy could be:

==========================
class Person(val name : String) {
   var address : Adress
}

class Child(val father : Person, val mother : Person) {
   val brothers = Buffer[Person]()
}

trait HasPassword {
   var pwd : String
}

class User(val login : String) extends User with HasPassword {
...
}
==========================

It is of course just an example of the different use cases that I encountered, and maybe there are a lots of other than just class and/or trait with val and/or vars and/or (im)mutable collections.

So, what are the best practices to minimize code duplication and be able to make deep copies of objects ?

Case with only vals (immutable state in general) are rather simple, but there are all the others...

I saw somewhere that 2.8 named/defaults arguments may bring some great enhancement in this area, but I can't find any resources about that anymore.


Thanks in advance for all the good advice you scalazies will give !

--
Francois Armand

Sebastien Bocq
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
Or maybe better, no new keyword as it would cause many issues.

val seb = new fanf {val name="seb"}

2009/10/31 Sébastien Bocq <sebastien.bocq@gmail.com>
Hi,

I'm struggling with this too. Is there any cloning support in 2.8 like found in some prototype-based languages?

Maybe 'clone' could be a keyword used like this:

trait Person {
  val name:String 
  val other = "XXX"
}

trait Question  {
  val q:String
}

val fanf = new Person with Question {val name="fanf"; val q="What about clone?"}

val seb = clone fanf {val name="seb"}

Any suggestion?

Thanks,
Sebastien

2009/10/23 Francois <fanf42@gmail.com>
Hello,

I'm in the process of building a my domain model and I'm wondering what are the Scala best practices regarding the cloning subject for inheritance hierarchy.

A typical example of hierarchy could be:

==========================
class Person(val name : String) {
   var address : Adress
}

class Child(val father : Person, val mother : Person) {
   val brothers = Buffer[Person]()
}

trait HasPassword {
   var pwd : String
}

class User(val login : String) extends User with HasPassword {
...
}
==========================

It is of course just an example of the different use cases that I encountered, and maybe there are a lots of other than just class and/or trait with val and/or vars and/or (im)mutable collections.

So, what are the best practices to minimize code duplication and be able to make deep copies of objects ?

Case with only vals (immutable state in general) are rather simple, but there are all the others...

I saw somewhere that 2.8 named/defaults arguments may bring some great enhancement in this area, but I can't find any resources about that anymore.


Thanks in advance for all the good advice you scalazies will give !

--
Francois Armand


sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /

I seem to remember hearing that 2.8 will use named and default arguments to
automatically generate copy methods for case classes, as described here:
http://www.scala-lang.org/node/2075

val seb = fanf.copy(name="seb")

You could achieve the same result yourself for non-case classes:

def copy (name = this.name, other = this.other) = new Person(name, other)

I'm not using the 2.8 nightlies myself, so does somebody who is want to
confirm this?

Sébastien Bocq wrote:
>
> Or maybe better, no new keyword as it would cause many issues.
>
> val seb = new fanf {val name="seb"}
>
> 2009/10/31 Sébastien Bocq
>
>> Hi,
>>
>> I'm struggling with this too. Is there any cloning support in 2.8 like
>> found in some prototype-based languages?
>>
>> Maybe 'clone' could be a keyword used like this:
>>
>> trait Person {
>> val name:String
>> val other = "XXX"
>> }
>>
>> trait Question {
>> val q:String
>> }
>>
>> val fanf = new Person with Question {val name="fanf"; val q="What about
>> clone?"}
>>
>> val seb = clone fanf {val name="seb"}
>>
>> Any suggestion?
>>
>> Thanks,
>> Sebastien
>>
>> 2009/10/23 Francois
>>
>> Hello,
>>>
>>> I'm in the process of building a my domain model and I'm wondering what
>>> are the Scala best practices regarding the cloning subject for
>>> inheritance
>>> hierarchy.
>>>
>>> A typical example of hierarchy could be:
>>>
>>> ==========================
>>> class Person(val name : String) {
>>> var address : Adress
>>> }
>>>
>>> class Child(val father : Person, val mother : Person) {
>>> val brothers = Buffer[Person]()
>>> }
>>>
>>> trait HasPassword {
>>> var pwd : String
>>> }
>>>
>>> class User(val login : String) extends User with HasPassword {
>>> ...
>>> }
>>> ==========================
>>>
>>> It is of course just an example of the different use cases that I
>>> encountered, and maybe there are a lots of other than just class and/or
>>> trait with val and/or vars and/or (im)mutable collections.
>>>
>>> So, what are the best practices to minimize code duplication and be able
>>> to make deep copies of objects ?
>>>
>>> Case with only vals (immutable state in general) are rather simple, but
>>> there are all the others...
>>>
>>> I saw somewhere that 2.8 named/defaults arguments may bring some great
>>> enhancement in this area, but I can't find any resources about that
>>> anymore.
>>>
>>>
>>> Thanks in advance for all the good advice you scalazies will give !
>>>
>>> --
>>> Francois Armand
>>>
>>
>>
>
>

David Hall 4
Joined: 2009-08-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /

On Sat, Oct 31, 2009 at 3:39 PM, Marcus Downing wrote:
>
> I seem to remember hearing that 2.8 will use named and default arguments to
> automatically generate copy methods for case classes, as described here:
> http://www.scala-lang.org/node/2075
>
>  val seb = fanf.copy(name="seb")
>
> You could achieve the same result yourself for non-case classes:
>
>  def copy (name = this.name, other = this.other) = new Person(name, other)
>
> I'm not using the 2.8 nightlies myself, so does somebody who is want to
> confirm this?

I use this, and it makes me happy.

Sebastien Bocq
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
Thanks for the suggestion but unfortunately this pattern doesn't scale with mixin composition. For example if X is a trait, you can't do "new A with X" and inherit automatically the copy behavior of X. Take for example the trait Person I made earlier, you can't implement copy there.

My question is how to use mixins and code the immutable way in a scalable manner?


2009/10/31 David Hall <dlwh@cs.berkeley.edu>
On Sat, Oct 31, 2009 at 3:39 PM, Marcus Downing <marcus@minotaur.it> wrote:
>
> I seem to remember hearing that 2.8 will use named and default arguments to
> automatically generate copy methods for case classes, as described here:
> http://www.scala-lang.org/node/2075
>
>  val seb = fanf.copy(name="seb")
>
> You could achieve the same result yourself for non-case classes:
>
>  def copy (name = this.name, other = this.other) = new Person(name, other)
>
> I'm not using the 2.8 nightlies myself, so does somebody who is want to
> confirm this?

I use this, and it makes me happy.

fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor / f

Sébastien Bocq a écrit :
> Or maybe better, no new keyword as it would cause many issues.
>
> val seb = new fanf {val name="seb"}

Well, for now, the best I came with is what I posted here:
http://fanf42.blogspot.com/2009/10/clone-objects-with-arguments-override...

It allows to make clone like that :

val fanf = new Person("fanf", "What's your name ?") { var age = 28 }
val fanf2 = fanf.copy
val foo = fanf.copyWith(name = "foo", age = "42")

But it leads to awful amount of code duplication in class hierrachy
because each daughter class has to declare it's own "copyWith" method
with all its ancestor named argument. And that means that if an ancestor
parameter is modified (added/suppressed or even just name changed), we
have to replicate the change in ALL the hierarchy.

So, for now, I'm really disappointed with named argument and cloning in
Scala.

sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor / f

Francois-17 wrote:
>
> So, for now, I'm really disappointed with named argument and cloning in
> Scala.
>

It does exactly the right thing for case classes, automatically generates a
copy() method. It's only normal classes that it doesn't do it for, and it's
assumed that the values of a non-case class might be sufficiently
complicated that a straightforward copy is inaccurate.

For example, what happens if you attempt to copy() a JDBC Connection? Or a
File?

fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor / f

On 04/11/2009 16:45, Marcus Downing wrote:
> It does exactly the right thing for case classes, automatically generates a
> copy() method. It's only normal classes that it doesn't do it for, and it's
> assumed that the values of a non-case class might be sufficiently
> complicated that a straightforward copy is inaccurate.
>
> For example, what happens if you attempt to copy() a JDBC Connection? Or a
> File?

I didn't mean that Scala should auto-generate clone or copy methods, I
meant that Named arguments seemed to be a fabulous tool to build really
powerful and flexible copy method in Scala, but that my experiment so
for is quite disapointing, especially when class hierarchies and/or vars
are involved, with a lot of tedious code to write and almost copy/paste
in each level of the hierarchy.

Of course, there is no magic, and the semantic of a copy method should
be let to the user - safe in non ambiguous cases like for immutable case
classes with no parents defining a copy method.

For now, I will stay with what I have, but I will have to spend some
strict tests process on that methods to check them along their life...

--
Francois Armand
http://fanf42.blogspot.com

Sebastien Bocq
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
I played a bit with those concepts and came up with the contrived example below. Although it is probably better this way, `copy` in case classes doesn't perform a real copy of the object, not even a shallow copy.

scala> trait File {
     | val filename:String
     | var fd:Int = _
     | def open() {fd = filename.hashCode}
     | def write(s:String) = println("Writing " + s + " to "
     | }
defined trait File

scala> case class Person(name:String) extends File {
     | val filename = "/home/"+name+"/config.json"
     | }
defined class Person

scala> val seb = Person("seb")
seb: Person = Person(seb)

scala> seb.open

scala> seb.write("Hello")
Writing Hello to -1245076908

scala> val fanf = seb.copy(name = "fanf")
fanf: Person = Person(fanf)

scala> fanf.write("Hello")
Writing Hello to 0

scala> fanf.filename
res8: java.lang.String = /home/fanf/config.json

Although it would yield a similar objects, I can't mixin behaviors dynamically into case classes:

scala> case class Person(name:String)
defined class Person

scala> val seb = Person(name:String) with File {
<console>:1: error: ';' expected but 'with' found.
       val seb = Person(name:String) with File {

In my opinion, as long as this is not possible to copy easily other objects than those obtained from case classes, Scala will impose limitations that make immutability unpractical at a large scale. It is probably not for tomorrow but it would be nice if Scala could fuse OO, FP and prototype-based paradigms in a safe manner!

Thanks for the feedback,
Sebastien

2009/11/4 Marcus Downing <marcus@minotaur.it>


Francois-17 wrote:
>
> So, for now, I'm really disappointed with named argument and cloning in
> Scala.
>

It does exactly the right thing for case classes, automatically generates a
copy() method. It's only normal classes that it doesn't do it for, and it's
assumed that the values of a non-case class might be sufficiently
complicated that a straightforward copy is inaccurate.

For example, what happens if you attempt to copy() a JDBC Connection? Or a
File?
--
View this message in context: http://old.nabble.com/Scala-2.8-best-practices-about-clone---copy-constructor---factory---etc---tp26023568p26198701.html
Sent from the Scala - User mailing list archive at Nabble.com.


sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /

Sébastien Bocq wrote:
>
> Although it would yield a similar objects, I can't mixin behaviors
> dynamically into case classes:
>
> scala> case class Person(name:String)
> defined class Person
>
> scala> val seb = Person(name:String) with File {
> :1: error: ';' expected but 'with' found.
> val seb = Person(name:String) with File {
>

That's because Person(name) isn't a constructor, it's a method of the Person
companion object. If you use the constructor then it works just fine:

scala> val seb = new Person(name) with File

To explain the difference (if this is below your level I apologise), when
you write a case class the compiler automatically generates a companion
object with an apply() method that can be used in place of a constructor
(and a matching unapply method for pattern matching). So writing this:

case class Person (name: String)

Is like writing this:

class Person (name: String) {
// a whole bunch of other auto-generated stuff
}

object Person {
def apply(name: String) = new Person(name)
}

And then writing Person(name) is a shortcut for Person.apply(name)

I don't understand what it is you don't like about the named and default
arguments. They provide a neat pattern for writing copy methods (far neater
and safer than the pattern you came up with on your blog). The copy method
is automatically created for case classes, but not for ordinary classes.
This is entirely in keeping with the rest of the language: a case class is
an immutable data type where you can trust that the compiler knows best, an
non-case class is one where you define the behaviour for yourself.

fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor / f

On 05/11/2009 14:05, Marcus Downing wrote:
> I don't understand what it is you don't like about the named and default
> arguments. They provide a neat pattern for writing copy methods (far neater
> and safer than the pattern you came up with on your blog).

OK, so it's the neat pattern that I'm missing and looking for. And I'm
pretty sure I used named/default arguments on my blog.

So, my requirements are:
- I have classes with vals and vars
- these classes are organized in hierarchies and aspects (I have both
traits and classes hierarchies)
That means that I'm out of the "case class" really specific case that is
the simple one that works well.

Given only that, I want to find a pattern to let developers implement
deep copies of instances writting the less code (and so, using again the
most code from parents/traits/factories/whatever), and where I have the
possibility to modify some values of the copy on the fly, based on the
properties names (so clearly here, default and named arguments are
involved). Ah, of course, I do want to have a returned copy of the same
type as the copied object. Traits included.

So please, show me the pattern, I'm really just asking for that !

Some hints about what I had to deal with:
- vars and constructors don't go well together with inheritance ;
- if traits are involved, you will need some kind of "only copy the
property I own but deals correctly with input/output type of the clone"
- covariance and inheritance is funny to deal with
- named arguments and inheritance is funny, too. Well, if you like to
copy/paste lists of arguments.

--
Francois Armand

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
On Thu, Nov 5, 2009 at 9:26 AM, Francois <fanf42@gmail.com> wrote:

So please, show me the pattern, I'm really just asking for that !


There's not really a good generic way to deal with what you want. Much like equality, cloning, and particularly deep cloning, are context specific.
I've tried this before through reflection and it's not pretty.
Dean Wampler
Joined: 2008-12-26,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
+1. I also can't remember the last time I really needed a deep clone of an object graph. It has performance issues, in addition to the issues already discussed. Unless my memory fails me, I've always found an alternative design.
My view is that the best, general model is a persistent data structure, like the Bagwell persistent collections used in Clojure for STM and "coming soon to a Scala near you". It safely handles copy-on-write behavior, leaving other clients of the original data structure unaffected. Are there any scenarios where copy-on-write behavior won't work and deep cloning is essential?
dean

On Thu, Nov 5, 2009 at 11:13 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Thu, Nov 5, 2009 at 9:26 AM, Francois <fanf42@gmail.com> wrote:

So please, show me the pattern, I'm really just asking for that !


There's not really a good generic way to deal with what you want. Much like equality, cloning, and particularly deep cloning, are context specific.
I've tried this before through reflection and it's not pretty.



--
Dean Wampler
coauthor of "Programming Scala" (O'Reilly)
-  http://programmingscala.com

twitter: @deanwampler, @chicagoscala
Chicago-Area Scala Enthusiasts (CASE):
-  http://groups.google.com/group/chicagoscala
-  http://www.meetup.com/chicagoscala/ (Meetings)
http://www.linkedin.com/in/deanwampler
http://www.polyglotprogramming.com
http://aquarium.rubyforge.org
http://www.contract4j.org
Sebastien Bocq
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
2009/11/5 Marcus Downing <marcus@minotaur.it>

I don't understand what it is you don't like about the named and default
arguments. They provide a neat pattern for writing copy methods (far neater
and safer than the pattern you came up with on your blog). The copy method
is automatically created for case classes, but not for ordinary classes.
This is entirely in keeping with the rest of the language: a case class is
an immutable data type where you can trust that the compiler knows best, an
non-case class is one where you define the behaviour for yourself.


Personally I really like them, it is just that I miss this feature beyond case classes where I know it is also safe to copy the object. If Person is a regular class I can't use the neat copy method anymore but I can mixin traits dynamically. If Person is a case class, I can copy it for free but I can't mixin traits dynamically anymore. That was the idea behind the example. I understand the challenge and I'm wondering if there would be a way to unify these approaches in the future.
sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor / f

Deep copying is counter to the functional spirit of immutable objects and
case classes that Scala espouses, so you'll have to write it yourself.
However, the same pattern can still be used, with just one adaptation: you
need to call the corresponding method of each of your variables:

class Foo (name: String) {
def deepCopy(name = name) = new Foo(name)
}

class Bar (var foo: Foo) {
def deepCopy(foo = foo.deepCopy) = new Bar(foo)
}

Strings don't need deep copying so Foo.deepCopy just needs to refer to its
parameter. Foos apparently do need deep copying, so Bar.deepCopy calls
foo.deepCopy as its parameter - unless the foo parameter is specified when
the method is called. You may need to do some functional gymnastics to make
sure it doesn't call foo.deepCopy unnecessarily.

To apply this to a hierarchy of concrete classes, you will of course have to
put a version of the deepCopy method into all of the classes, including
children.

Returning the correct type from objects to which you've applied a trait
above that of the class itself is trickier. My first impulse is to tell you
not to do it, but I have to assume you have your reasons. Unless somebody
can come up with a better way, you're probably going to have to use good old
Java reflection for that bit - however, you can wrap that bit of ugliness up
in a trait:

trait DeepCopyable {
def internalDeepCopy(args: _*) = {
// ugly reflection to create a new instance of
val thisClass = classOf[this]
thisClass.newInstance(args)
}
}

Which would then be applied like this:

class Bar (var foo: Foo) {
def deepCopy(foo = foo.deepCopy) = internalDeepCopy(foo)
}

Yes, using reflection will be slower than an ordinary constructor. That's
the price for deliberately walking off the nice clean fuctional path that
Scala has laid out for you, onto the muddy grass of imperativeness.

**** Note that none of the above is actually tested, I'm just braindumping.

Francois-17 wrote:
>
> On 05/11/2009 14:05, Marcus Downing wrote:
>> I don't understand what it is you don't like about the named and default
>> arguments. They provide a neat pattern for writing copy methods (far
>> neater
>> and safer than the pattern you came up with on your blog).
>
> OK, so it's the neat pattern that I'm missing and looking for. And I'm
> pretty sure I used named/default arguments on my blog.
>
> So, my requirements are:
> - I have classes with vals and vars
> - these classes are organized in hierarchies and aspects (I have both
> traits and classes hierarchies)
> That means that I'm out of the "case class" really specific case that is
> the simple one that works well.
>
> Given only that, I want to find a pattern to let developers implement
> deep copies of instances writting the less code (and so, using again the
> most code from parents/traits/factories/whatever), and where I have the
> possibility to modify some values of the copy on the fly, based on the
> properties names (so clearly here, default and named arguments are
> involved). Ah, of course, I do want to have a returned copy of the same
> type as the copied object. Traits included.
>
> So please, show me the pattern, I'm really just asking for that !
>
> Some hints about what I had to deal with:
> - vars and constructors don't go well together with inheritance ;
> - if traits are involved, you will need some kind of "only copy the
> property I own but deals correctly with input/output type of the clone"
> - covariance and inheritance is funny to deal with
> - named arguments and inheritance is funny, too. Well, if you like to
> copy/paste lists of arguments.
>
> --
> Francois Armand
>
>

Sébastien Lorion
Joined: 2009-07-27,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
How serialization would fare as a way to do deep cloning with Scala ? Can't imagine having to do that manually or even worse via reflection ...

Sébastien

On Thu, Nov 5, 2009 at 14:20, Marcus Downing <marcus@minotaur.it> wrote:

Deep copying is counter to the functional spirit of immutable objects and
case classes that Scala espouses, so you'll have to write it yourself.
However, the same pattern can still be used, with just one adaptation: you
need to call the corresponding method of each of your variables:

class Foo (name: String) {
 def deepCopy(name = name) = new Foo(name)
}

class Bar (var foo: Foo) {
 def deepCopy(foo = foo.deepCopy) = new Bar(foo)
}

Strings don't need deep copying so Foo.deepCopy just needs to refer to its
parameter. Foos apparently do need deep copying, so Bar.deepCopy calls
foo.deepCopy as its parameter - unless the foo parameter is specified when
the method is called. You may need to do some functional gymnastics to make
sure it doesn't call foo.deepCopy unnecessarily.

To apply this to a hierarchy of concrete classes, you will of course have to
put a version of the deepCopy method into all of the classes, including
children.

Returning the correct type from objects to which you've applied a trait
above that of the class itself is trickier. My first impulse is to tell you
not to do it, but I have to assume you have your reasons. Unless somebody
can come up with a better way, you're probably going to have to use good old
Java reflection for that bit - however, you can wrap that bit of ugliness up
in a trait:

trait DeepCopyable {
 def internalDeepCopy(args: _*) = {
   // ugly reflection to create a new instance of
   val thisClass = classOf[this]
   thisClass.newInstance(args)
 }
}

Which would then be applied like this:

class Bar (var foo: Foo) {
 def deepCopy(foo = foo.deepCopy) = internalDeepCopy(foo)
}

Yes, using reflection will be slower than an ordinary constructor. That's
the price for deliberately walking off the nice clean fuctional path that
Scala has laid out for you, onto the muddy grass of imperativeness.

**** Note that none of the above is actually tested, I'm just braindumping.



Francois-17 wrote:
>
> On 05/11/2009 14:05, Marcus Downing wrote:
>> I don't understand what it is you don't like about the named and default
>> arguments. They provide a neat pattern for writing copy methods (far
>> neater
>> and safer than the pattern you came up with on your blog).
>
> OK, so it's the neat pattern that I'm missing and looking for. And I'm
> pretty sure I used named/default arguments on my blog.
>
> So, my requirements are:
> - I have classes with vals and vars
> - these classes are organized in hierarchies and aspects (I have both
> traits and classes hierarchies)
> That means that I'm out of the "case class" really specific case that is
> the simple one that works well.
>
> Given only that, I want to find a pattern to let developers implement
> deep copies of instances writting the less code (and so, using again the
> most code from parents/traits/factories/whatever), and where I have the
> possibility to modify some values of the copy on the fly, based on the
> properties names (so clearly here, default and named arguments are
> involved). Ah, of course, I do want to have a returned copy of the same
> type as the copied object. Traits included.
>
> So please, show me the pattern, I'm really just asking for that !
>
> Some hints about what I had to deal with:
> - vars and constructors don't go well together with inheritance ;
> - if traits are involved, you will need some kind of "only copy the
> property I own but deals correctly with input/output type of the clone"
> - covariance and inheritance is funny to deal with
> - named arguments and inheritance is funny, too. Well, if you like to
> copy/paste lists of arguments.
>
> --
> Francois Armand
>
>

--
View this message in context: http://old.nabble.com/Scala-2.8-best-practices-about-clone---copy-constructor---factory---etc---tp26023568p26218569.html
Sent from the Scala - User mailing list archive at Nabble.com.


Sebastien Bocq
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /


2009/11/5 Marcus Downing <marcus@minotaur.it>


trait DeepCopyable {
 def internalDeepCopy(args: _*) = {
   // ugly reflection to create a new instance of
   val thisClass = classOf[this]
   thisClass.newInstance(args)
 }
}

Which would then be applied like this:

class Bar (var foo: Foo) {
 def deepCopy(foo = foo.deepCopy) = internalDeepCopy(foo)
}

 Suppose I just use immutable classes and traits, no vars,  in most parts of my code. How would I implement a ShallowCopyable trait myself? I can't.
phkoester
Joined: 2009-08-23,
User offline. Last seen 42 years 45 weeks ago.
Lazy Vals Thread-Safe?

Dear list,

short question in the hope of a short answer: Are lazy vals in Scala
implemented in a thread-safe fashion?

---Ph.

David Hall 4
Joined: 2009-08-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Lazy Vals Thread-Safe?

yes. it uses double checked locking.

Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: Lazy Vals Thread-Safe?

<4AEE8C15.50402@gmail.com> <26198701.post@talk.nabble.com>

<26213654.post@talk.nabble.com> <4AF2EEA6.3090806@gmail.com>

<26218569.post@talk.nabble.com>

<4AF3DD64.2070004@web.de>

<5efa98b30911060042k391b6b3eo8b3775402110b859@mail.gmail.com>
MIME-Version: 1.0

--_623dd273-057b-4b0e-bc8b-e60aa69f1120_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

> yes. it uses double checked locking.
>=20

ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 2 days ago.
RE: Lazy Vals Thread-Safe?

On Fri, 2009-11-06 at 10:00 +0000, christopher marshall wrote:
> > yes. it uses double checked locking.
> >
> > -- David
>
> Really? How is DCL thread-safe using raw synchronization in Java? Is
> the variable marked as volatile or is there a hidden juc.ReadWriteLock
> lurking somewhere?

There's a bitmap that's marked as volatile. The bitmap is used to check
if one or more lazy val fields have been initialised.

Best,
Ismael

ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: Lazy Vals Thread-Safe?

I had posted the implementation here:

http://code-o-matic.blogspot.com/2009/05/double-checked-locking-idiom-sw...

2009/11/6 christopher marshall :
>> yes. it uses double checked locking.
>>

phkoester
Joined: 2009-08-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Lazy Vals Thread-Safe?

> Really? How is DCL thread-safe using raw synchronization in Java? Is the
> variable marked as volatile or is there a hidden juc.ReadWriteLock
> lurking somewhere?

If you implement double-checking like this:

if (val == null) { // Redundant check; optimization
synchronized (lock) {
if (val == null) {
val = ...
}
}
}
return val;

then `val' needn't, and shouldn't, be volatile here.

---Ph.

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
On Fri, Nov 6, 2009 at 12:51 AM, Sébastien Bocq <sebastien.bocq@gmail.com> wrote:
Suppose I just use immutable classes and traits, no vars,  in most parts of my code. How would I implement a ShallowCopyable trait myself? I can't.

extends Cloneable?
nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Scala 2.8 best practices about clone / copy constructor /
On Fri, Nov 6, 2009 at 8:32 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Fri, Nov 6, 2009 at 12:51 AM, Sébastien Bocq <sebastien.bocq@gmail.com> wrote:
Suppose I just use immutable classes and traits, no vars,  in most parts of my code. How would I implement a ShallowCopyable trait myself? I can't.

extends Cloneable?

Sorry, not paying attention.

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