Why mutable/immutable can't be valid class qualifier?

Discussion in 'Java' started by hiwa, Mar 7, 2006.

  1. hiwa

    hiwa Guest

    I used to be uneasy at the fact that immutability
    of a class object is only casually mentioned in
    some tiny corner of the API documentation.

    And I wonder why we can't do:

    public immutable class BigDecimal

    or, implementing a marker inteface:

    public class BigDecimal
    All Implemented Interfaces:
    Immutable, Serializable, Comparable<BigDecimal>
    hiwa, Mar 7, 2006
    #1
    1. Advertising

  2. hiwa

    Eric Sosman Guest

    hiwa wrote On 03/07/06 04:36,:
    > I used to be uneasy at the fact that immutability
    > of a class object is only casually mentioned in
    > some tiny corner of the API documentation.
    >
    > And I wonder why we can't do:
    >
    > public immutable class BigDecimal
    >
    > or, implementing a marker inteface:
    >
    > public class BigDecimal
    > All Implemented Interfaces:
    > Immutable, Serializable, Comparable<BigDecimal>


    Probably because "immutable" can be hard to pin down
    satisfactorily. Example:

    final class ImmutableThing {

    // these members are assumed immutable, too:
    private final SomeThing x;
    private final OtherThing y;
    private final ThirdThing z;

    ImmutableThing() {
    x = new SomeThing("surprise");
    y = new OtherThing("fear");
    z = new ThirdThing("there is no third thing");
    }

    public boolean equals(Object obj) {
    if (! (obj instanceof ImmutableThing))
    return false;
    ImmutableThing that = (ImmutableThing)obj;
    return x.equals(that.x) && y.equals(that.y)
    && z.equals(that.z);
    }

    private int lazyHash; // computed only if needed

    public int hashCode() {
    if (lazyHash == 0) {
    // do the expensive hashing only once
    laxyHash = x.hashCode() ^ y.hashCode()
    ^ z.hashCode();
    }
    return lazyHash;
    }
    }

    The crucial question: Is this class immutable? One
    argument says it's not, because the lazyHash member's value
    can change after construction. Another argument says that
    doesn't matter, because lazyHash can only be observed by
    calling hashCode() and hashCode() returns a constant value.
    Both are right, in their own terms -- and how are you going
    to define the semantics of a keyword or marker interface so
    as to make both sides happy? If you can't, how will you
    placate those on the unhappy side?

    There's quite a lot about Java that lives solely in the
    documentation. For instance, the compiler would accept

    class Stupid implements Comparable {
    public int compareTo(Object obj) {
    return 42;
    }
    }

    Only the JavaDoc tells us that this does not fulfill the
    contract of the Comparable interface; the compiler is not
    aware of the contract and so cannot enforce it. Immutabilty
    (both the quality itself and the sense in which it is to be
    understood for the class at hand) is a similar case. Or as
    a colleague once observed, "The compiler is not a substitute
    for self-discipline."

    --
    Eric Sosman, Mar 7, 2006
    #2
    1. Advertising

  3. hiwa

    Oliver Wong Guest

    "Eric Sosman" <> wrote in message
    news:dukfar$9pt$...
    >
    > Probably because "immutable" can be hard to pin down
    > satisfactorily. Example:
    >
    > final class ImmutableThing {
    >
    > // these members are assumed immutable, too:
    > private final SomeThing x;
    > private final OtherThing y;
    > private final ThirdThing z;
    >
    > ImmutableThing() {
    > x = new SomeThing("surprise");
    > y = new OtherThing("fear");
    > z = new ThirdThing("there is no third thing");
    > }
    >
    > public boolean equals(Object obj) {
    > if (! (obj instanceof ImmutableThing))
    > return false;
    > ImmutableThing that = (ImmutableThing)obj;
    > return x.equals(that.x) && y.equals(that.y)
    > && z.equals(that.z);
    > }
    >
    > private int lazyHash; // computed only if needed
    >
    > public int hashCode() {
    > if (lazyHash == 0) {
    > // do the expensive hashing only once
    > laxyHash = x.hashCode() ^ y.hashCode()
    > ^ z.hashCode();
    > }
    > return lazyHash;
    > }
    > }
    >
    > The crucial question: Is this class immutable? One
    > argument says it's not, because the lazyHash member's value
    > can change after construction. Another argument says that
    > doesn't matter, because lazyHash can only be observed by
    > calling hashCode() and hashCode() returns a constant value.
    > Both are right, in their own terms


    Excellent example. Here's another one which shows why a class which may
    appear to be immutable to the compiler, but appears to NOT be immutable to
    the user.

    <pseudocode>
    class FakeImmutable {
    private final FileWriter out;
    private final FileReader in;

    public FakeImmutable() {
    File f = createTempFile("fake","immutable");
    out = new FileWriter(f);
    in = new FileReader(f);
    }

    public synchronized String getX() {
    /*Read from the in, and return whatever you got.*/
    }

    public synchronized void setX(String newValue) {
    /*Clear the file, and write the newValue to the file.*/
    }
    }
    </pseudocode>

    From the compiler's perspective, this is an immutable class. That is,
    all of its fields are final (constant). But from the user's perspective, it
    appears to have a field called X which is settable.

    - Oliver
    Oliver Wong, Mar 7, 2006
    #3
  4. hiwa

    hiwa Guest

    Eric Sosman wrote:
    > Probably because "immutable" can
    > be hard to pin down satisfactorily.


    Oliver Wong wrote:
    > immutable to the compiler, but appears
    > to NOT be immutable to the user


    Well, then, what could be the definition or criteria
    Java API documentation uses when they call a class
    object immutable? There must be one, not two or more.
    hiwa, Mar 8, 2006
    #4
  5. hiwa

    Oliver Wong Guest

    "hiwa" <> wrote in message
    news:...
    > Eric Sosman wrote:
    >> Probably because "immutable" can
    >> be hard to pin down satisfactorily.

    >
    > Oliver Wong wrote:
    >> immutable to the compiler, but appears
    >> to NOT be immutable to the user

    >
    > Well, then, what could be the definition or criteria
    > Java API documentation uses when they call a class
    > object immutable? There must be one, not two or more.


    They mean "from the user's perspective". That is, there does not exist a
    sequence of calls that the user can make so that the apparent state of the
    object changes.

    Note that using the definition I just gave, Eric's example is immutable,
    but mine is not. The *INTERNAL* state of Eric's example changes, but the
    apparent state does not. So it is immutable.

    Whereas in my example, the INTERNAL state does not change, but the
    apparent state does change, so my class is not immutable (even though all of
    its fields are declared final).

    The basic conclusion is that humans can decide whether a class is
    immutable or not, but a compiler can't. That is why there isn't an
    "immutable" keyword for classes.

    - Oliver
    Oliver Wong, Mar 8, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    368
    John Roth
    Apr 15, 2004
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,762
    Smokey Grindel
    Dec 2, 2006
  3. Replies:
    5
    Views:
    398
  4. Bernard Lim

    Immutable and Mutable Types

    Bernard Lim, Mar 17, 2008, in forum: Python
    Replies:
    16
    Views:
    635
    Terry Reedy
    Mar 19, 2008
  5. Deb Wyatt

    immutable vs mutable

    Deb Wyatt, Jun 3, 2014, in forum: Python
    Replies:
    13
    Views:
    53
    Mark H Harris
    Jun 4, 2014
Loading...

Share This Page