Scala's lists are immutable, yes. But they aren't thread-safe.

That's because internally scala lists *ARE* mutable. In an attempt to
work around JVM limitations and make scala fast, scala lists are
actually mutable for a while as long as nobody reads them, in order to
make repeated adds fast. So, this:

[a :: b :: c :: d :: e :: Nil]

in scala does NOT in fact create 4 lists. It creates just one and
makes a bunch of add calls.

Unfortunately, even Odersky's out of this world genius is fallible.
Specifically, there are conditions where a shared immutable list in
scala cause multi threading bugs. you know the type - impossible to
debug, tend to never show up when a debugger is running, race
conditions, bugs that are only reproducible on 2-core or even 4-core
systems, and in general pains that can take you years to solve.

Long story short: Scala is not a panacea. In fact, in this particular
aspect, Scala sucks.

Silver lining in this thundercloud? The regulars on FreeNode #scala
have submitted patches, which are only a little slower than the
current implementation and definitely safe.

On Dec 5, 11:09 am, "Viktor Klang" <[EMAIL PROTECTED]> wrote:
> Yes, I agree, arrays is a lame "corner"-case.
>
> However, my opinion is that the concept of array as in "contigous memory
> area that is efficient for a processor to process" is an
> implementation/optimization feature, and not a language feature.
> While I fully agree that many programmers couldn't live without the precious
> array, I truely hope that a VM could use them "under the hood" to provide
> better performance for certain List use-cases.
>
> In Java, you could probably manage very well with only Buffer and ArrayList.
>
> Scala Lists are immutable, and can therefor be shared freely.
>
> What's your take on this?
>
> Cheers,
> Viktor
>
>
>
> On Thu, Dec 4, 2008 at 11:33 PM, hlovatt <[EMAIL PROTECTED]> wrote:
>
> > The Scala case classes only do the simple cases, consider:
>
> > object Main {
> >  case class Foo( values : Array[Int] ) {
> >      var anotherValue : Int = 1
> >  }
>
> >  def main( args : Array[String] ) = {
> >    val a = Array( 1, 2, 3 )
> >    val f1 = Foo( a )
> >    println( f1.values.toString )
> >    a(0) = 2
> >    println( f1.values.toString )
> >    val f2 = Foo( a )
> >    f2.anotherValue = 2
> >    println( f1 == f2 )
> >  }
> > }
>
> > It prints:
>
> > Array(1, 2, 3)
> > Array(2, 2, 3)
> > true
>
> > So no it doesn't deep copy arguments and it also only uses the fields
> > of the constructor for equals, hash, etc. and not any other fields.
> > The facilities in PEC solve both these problems (http://
> > pec.dev.java.net/compile/javadoc/pec/compile/immutable/
> > AbstractImmutable.html<http://pec.dev.java.net/compile/javadoc/pec/compile/immutable/Abstrac...>
> > ).
>
> > On Dec 5, 9:10 am, "Michael Lee" <[EMAIL PROTECTED]> wrote:
> > > Does Scalar support the defensive copy of mutable attributes?  For
> > examples,
> > > if the constructor takes in in an array, does it automatically 'clone'
> > the
> > > array for internal attribute?  How about 'get' method?
> > > Thanks in advance.
>
> > > On Thu, Dec 4, 2008 at 4:05 PM, Viktor Klang <[EMAIL PROTECTED]>
> > wrote:
> > > > What I do in Scala:
>
> > > > case class Person(val firstName : String, val lastName : String)
>
> > > > then I get correct equals, hashCode, a toString and pattern-matching
> > and a
> > > > concise creation syntax:
>
> > > > val person = Person("Keith","Haber")
>
> > > > So instead of 30+ lines of Java, I get 1 line of Scala, with more
> > > > functionality ;)
>
> > > > </endShamelessPlug>
>
> > > > :)
>
> > > > On Thu, Dec 4, 2008 at 5:45 PM, Keith Haber <[EMAIL PROTECTED]> wrote:
>
> > > >> When I want to make an immutable type with a lot of attributes.  I
> > > >> generally like to use a static inner class as a builder object.
> > > >> Here's an example with just two attributes.
>
> > > >> public final class Person{
>
> > > >>   private final String firstName;
> > > >>   private final String lastName;
>
> > > >>   public Person(String firstName, String lastName){
> > > >>      super();
> > > >>      this.firstName = firstName;
> > > >>      this.lastName = lastName;
> > > >>   }
>
> > > >>   public String getFirstName(){return firstName;}
> > > >>   public String getLastName(){return lastName;}
>
> > > >>   public static class Builder {
> > > >>      private String firstName;
> > > >>      private String lastName;
>
> > > >>      public Builder setFirstName(String firstName){
> > > >>          this.firstName = firstName;
> > > >>          return this;
> > > >>      }
>
> > > >>      public Builder setLastName(String lastName){
> > > >>          this.lastName = lastName;
> > > >>          return this;
> > > >>      }
>
> > > >>      public Person newPerson(){
> > > >>          return new Person(firstName, lastName);
> > > >>      }
> > > >>  }
>
> > > >> }
>
> > > >> Then in my client code, I would do:
>
> > > >>    Person keith = new Person.Builder().setFirstName
> > > >> ("Keith").setLastName("Haber").newPerson();
>
> > > >> Or if I need to instantiate a lot of similar objects, I can hang on to
> > > >> my Builder object.  (Could be handy for constructing relatives, I
> > > >> suppose.)
>
> > > >> A nice thing about this approach is that I get the benefit of readable
> > > >> setters instead of working with long lists of meticulously ordered
> > > >> constructor arguments (not so big a deal with two attributes, but very
> > > >> helpful when working with six or more attributes), but my immutable
> > > >> objects don't have setters at all.
>
> > > >> And by making the builder class a static inner class, it's obvious
> > > >> which builder classes go with which immutable types -- it's always
> > > >> named <immutable type name>.Builder.
>
> > > >> In episode 219 they talked about objects having a "construct phase"
> > > >> with setters and a "use phase" when the object construction is
> > > >> "finished."  To my mind this approach is reasonably close to that
> > > >> idea.
>
> > > >> Keith
>
> > > >> On Dec 3, 10:58 pm, hlovatt <[EMAIL PROTECTED]> wrote:
> > > >> > In 219 there was a long discussion about setting up an object and
> > then
> > > >> > making it immutable. There are a couple of ways of doing this in
> > Java
> > > >> > already:
>
> > > >> > public class FooArgs {
> > > >> >   public int x = 1; // 1 is default
> > > >> >   public int y = 2;
> > > >> >   public int z = 3;
> > > >> >   ...
>
> > > >> > }
>
> > > >> > public class Foo {
> > > >> >   public Foo( FooArgs args ) { ... }
> > > >> >   ...
>
> > > >> > }
>
> > > >> >   Foo foo = new Foo( new FooArgs() {{ x = 2 }} );
>
> > > >> > Another option is an immutable and mutable versions that inherit
> > from
> > > >> > a common base and implement a standard conversion interface. First
> > the
> > > >> > standard interface:
>
> > > >> > public interface ImmutableValueConversions {
> > > >> >   Immutable toImmutable() throws IllegalStateException;
> > > >> >   Value toValue();
>
> > > >> > }
>
> > > >> > Below is an integer example that uses an abstract class as the base
> > of
> > > >> > the hierarchy. You can also use interfaces. The abstract class is:
>
> > > >> >     8:public abstract class AbstractInteger extends AbstractValue
> > > >> >     9:    implements ImmutableValueConversions, InstanceFactory {
> > > >> >    10:    public abstract int getValue();
> > > >> >    11:
> > > >> >    12:    public abstract AbstractInteger instanceOfSelf( int value
> > );
> > > >> >    13:
> > > >> >    14:    public AbstractInteger add( final int rhs ) {
> > > >> >    15:        return instanceOfSelf( getValue() + rhs );
> > > >> >    16:    }
> > > >> >    17:}
>
> > > >> > Then the immutable version:
>
> > > >> >     9:public final class ImmutableInteger2 extends AbstractInteger
> > > >> >    10:    implements Immutable {
> > > >> >    11:    private final int value;
> > > >> >    12:
> > > >> >    13:    public ImmutableInteger2( final int value ) {
> > > >> >    14:        this.value = value;
> > > >> >    15:    }
> > > >> >    16:
> > > >> >    17:    public int getValue() {
> > > >> >    18:        return value;
> > > >> >    19:    }
> > > >> >    20:
> > > >> >    21:    public Immutable toImmutable() {
> > > >> >    22:        return this;
> > > >> >    23:    }
> > > >> >    24:
> > > >> >    25:    public Value toValue() {
> > > >> >    26:        return new ValueInteger( value );
> > > >> >    27:    }
> > > >> >    28:
> > > >> >    29:    public AbstractInteger instanceOfSelf( final int value ) {
> > > >> >    30:        return new ImmutableInteger2( value );
> > > >> >    31:    }
> > > >> >    38:}
>
> > > >> > And the value version:
>
> > > >> >     9:public final class ValueInteger extends AbstractInteger {
> > > >> >    10:    // Not final, this is the value version
> > > >> >    11:    private int value;
> > > >> >    12:
> > > >> >    13:    public ValueInteger( final int value ) {
> > > >> >    14:        this.value = value;
> > > >> >    15:    }
> > > >> >    16:
> > > >> >    17:    public int getValue() {
> > > >> >    18:        return value;
> > > >> >    19:    }
> > > >> >    20:
> > > >> >    21:    // Setter, this is the value version!
> > > >> >    22:    public void setValue( final int value ) {
> > > >> >    23:        this.value = value;
> > > >> >    24:    }
> > > >> >    25:
> > > >> >    26:    public Immutable toImmutable() {
> > > >> >    27:        return new ImmutableInteger2( value );
> > > >> >    28:    }
> > > >> >    29:
> > > >> >    30:    public Value toValue() {
> > > >> >    31:        return new ValueInteger( value );
> > > >> >    32:    }
> > > >> >    33:
> > > >> >    34:    public AbstractInteger instanceOfSelf( final int value ) {
> > > >> >    35:        return new ValueInteger( value );
> > > >> >    36:    }
> > > >> >    37:
> > > >> >    38:    // Set and add combined (+=), this is the value version!
> > > >> >    39:    public ValueInteger setAdd( final int rhs ) {
> > > >> >    40:        value += rhs;
> > > >> >    41:        return this;
> > > >> >    42:    }
> > > >> >    49:}
>
> > > >> > Then you can use these classes like this:
>
> > > >> >   ImmutableInteger i = (ImmutableInteger)( new
> > ValueInteger().setValue
> > > >> > ( 2 ).toValue() );
>
> > > >> > My own pet project, PEC, is an extensible compiler that can enforce
> > > >> > patterns, the above immutable pattern can be enforced. More details
> > > >> > from:
>
> > > >> >  http://pec.dev.java.net/nonav/frontpage.html
>
> > > >> > What do others do?
>
> > > > --
> > > > Viktor Klang
> > > > Senior Systems Analyst
>
> --
> Viktor Klang
> Senior Systems Analyst
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to