In article , Martin Krischik says... > >Am 28.05.2010, 07:25 Uhr, schrieb Luis Espinal : > >> I don't think that is much of an issue. Mutability is. This is a big >> issue for >> Java as it has turned out. The commonly accepted best practice now is to >> mark >> variables and parameters as final unless you know before hand that you >> want to >> change them. > >Which only makes the reference to the variable un-mutable, not the >content. Yes. Absolutely and you are right. I think I should say that comment is wrt of Java default behavior towards variable/parameter declarations vs Scala's. So, what we are referring to here is not so much immutability of class instances (which would be the ideal... see below), but immutability of values and arguments within expressions (a practical concession given the limits of the language). The argument here is values that are immutable (either manually as in Java or by default as in Scala) leads to writing code based (or mostly based) on expressions. When done properly, it tends to be succinct and yet readable. >That combined with language which can do only pass by reference >for all complex types and a Clonable interface which was badly sorted out >gives you a language where the protection a getter function should give >you is just not there - unless you make it a habit to use «return x.clone >()» [1]. > It's not just Cloneable that we have to deal with. It's also when implementing Serializable. Or forced to rely on automatic garbage collection without having reliable finalizer methods. Not having the C++ equivalent of const member functions and const return types can be quite hurtful, too. >And if we are at it - setter functions should use «this.x = x.clone ()». >Those who did Ada or C++ know that. In Ada setter and getter functions >usually take a copy and in C++ setter and getter functions take a >reference to a constant object. That is: not the reference is constant - >the object itself is constant (un-mutable). > You are going to have forgive my C++/Ada peasantry since I haven't touched either for more than a decade (since I left grad school.) Why exactly would we want (in Java) to return a clone wrt to a setter/getter? I could understand *that* in C++ wrt to implementing a getter for an entity "A" that returns a modifiable copy/clone of "A". But in Java (where we have no guarantees when an object is going to be reclaimed), we simply cannot do that. By default, we have to assume that if a getter returns a reference to an instance of a class that is not immutable (.ie. extensions of java.lang.Number or String), then we have the ability to modify it (while still being part of the enclosing class exposing the getter method.) That's the default modus operandi. Anything else (returning a deep or shallow clone, for instance) has to be explicitly documented. As you pointed out, however, a good and valid criticism can be made on Java regarding 1) passing everything by value and 2) working with object references only. Without having the C++ equivalent of const member functions and const return types, it is impossible to syntactically enforce immutability. We can only do so in Java by convention and by structuring our classes as either mutable and immutable (the later being Scala's route.) >As it is most setter and getter functions in Java are placebos - they give >you you the feeling to do it the proper OO way but you are don't! > >Martin > >[1] provided the class at hand implements the Clonable interface property >and does indeed do full deep copy. I'm not sure I follow here either. I'm saying this genuinely, and I'd be happy to see your POV on this subject. To me a chain of calls P.getQ.getR...X.getY.getZ is simply a chain of messages from the caller to an given entity(Z) all the way through different contexts. The accessed attribute can be very primitive or complex, mutable or immutable, all that depending on the nature of the message and the nature of the receiving entity. That is, its complexity (or lack thereof) is implementation-specific, and thus hidden by these getter and setter methods. Whether it is immutable or if it permits mutability of one or all of its attributes, that's specific of the entity's public interfaces. I'd grant that it will be better, more syntactic, finer grained way of controlling mutability, but its presence is not necessarily required for object-orientation. I won't argue, however, the sad fact a lot of people in Java don't understand that, and they end up simulating goto-based programming with their poorly constructed classes :) - Luis Espinal. luis.espinal@gmail.com ps... I'll add to the discussion that one thing we sorely miss in Java is the ability to write nested functions as in Ada, Pascal and ALGOL. IMO they lead to cleaner, more organized code.