From: Arved Sandstrom on
Jim Janney wrote:
[ SNIP ]

> When I think about immutability, it's usually in terms of objects that
> represent values: strings, numbers, geometric points, that kind of
> thing. Immutability is convenient here since it lets you ignore the
> difference between reference and value semantics. Allowing public
> references to mutable objects would interfere with that, but I don't
> know that my point of view is the right one.
>
> The JCIP people are interested in thread safety. They even claim that
> immutability implies thread safety, but that's not automatically true
> for lazily computed values. Java.lang.String is only thread safe
> because hashCode() is carefully written.

My thought process is somewhat like yours. I have the JCIP book, I think
it's a fine reference, and I appreciate why the JCIP authors talk about
immutability. My thinking of immutable objects as value objects fits
into a wider view I have of enforcing code stability, namely being more
aware of (and enforcing) when values change. In other words, if you want
to change the value of field X in object Y, create a new object that
copies Y and sets a new value for field X. As far as I'm concerned
objects are cheap, but defects aren't.

If classes are basically bundles of imperative code - which is the case
for most of Java - then it's a different discussion.

AHS

--
We�re surrounded. That simplifies our problem of getting to these people
and killing them.
-- Lewis B. Puller, North Korea, 1950
From: Tom Anderson on
On Sat, 17 Jul 2010, Lew wrote:

> On 07/17/2010 05:36 AM,
> Lew wrote:
>>> String is the most basic immutable class in the API.
>
> Tom Anderson wrote:
>> Object?
>
> You're tardy to the party on that one. Asked and answered and driven to
> the depths of absurdity upthread already.

Again, again!

tom

--
And dear lord, its like peaches in a lacy napkin. -- James Dearden
From: Peter Duniho on
Jim Janney wrote:
> When I think about immutability, it's usually in terms of objects that
> represent values: strings, numbers, geometric points, that kind of
> thing. Immutability is convenient here since it lets you ignore the
> difference between reference and value semantics. Allowing public
> references to mutable objects would interfere with that, but I don't
> know that my point of view is the right one.

Well, right or wrong I'm in agreement. IMHO it is not sufficient for a
supposedly immutable type to only ensure that the data it is storing
directly is immutable. It can only store data that itself is also
immutable. Otherwise, the various benefits that go along with
immutability no longer apply.

> The JCIP people are interested in thread safety. They even claim that
> immutability implies thread safety, but that's not automatically true
> for lazily computed values. Java.lang.String is only thread safe
> because hashCode() is carefully written.

Huh? In what way is hashCode() for java.lang.String "carefully written"?

I mean sure, there are ways that it could have been written incorrectly.
The main (only?) non-thread-safe mistake being to use the "hash" field
itself as the accumulator for the calculation. But otherwise it seems
like a pretty straightforward, obvious implementation to me (not
counting the fact that if a string has the great misfortune to actually
have a hash code of 0, the hash code will be recomputed every time
hashCode() is called).

Mainly, it's thread-safe not because any particularly increased care was
taken in writing the method, but rather because the things that
hashCode() relies on are not going to change after the class has been
initialized, and so even if the "hash" value has been calculated in one
thread but not yet visible in another, the worst that can happen is that
it gets calculated again.

I'd say that being immutable _does_ imply thread safety, even for lazily
computed values. The only way that assumption would break is if the
lazily computed values depends on something other than what's in the
class itself, in which case I'd say the class is broken.

I'm open to being proven wrong if someone has a counter-example.

Pete
From: Jim Janney on
Peter Duniho <NpOeStPeAdM(a)NnOwSlPiAnMk.com> writes:

> Jim Janney wrote:
>> When I think about immutability, it's usually in terms of objects that
>> represent values: strings, numbers, geometric points, that kind of
>> thing. Immutability is convenient here since it lets you ignore the
>> difference between reference and value semantics. Allowing public
>> references to mutable objects would interfere with that, but I don't
>> know that my point of view is the right one.
>
> Well, right or wrong I'm in agreement. IMHO it is not sufficient for
> a supposedly immutable type to only ensure that the data it is storing
> directly is immutable. It can only store data that itself is also
> immutable. Otherwise, the various benefits that go along with
> immutability no longer apply.
>
>> The JCIP people are interested in thread safety. They even claim that
>> immutability implies thread safety, but that's not automatically true
>> for lazily computed values. Java.lang.String is only thread safe
>> because hashCode() is carefully written.
>
> Huh? In what way is hashCode() for java.lang.String "carefully written"?
>
> I mean sure, there are ways that it could have been written
> incorrectly. The main (only?) non-thread-safe mistake being to use the
> "hash" field itself as the accumulator for the calculation. But
> otherwise it seems like a pretty straightforward, obvious
> implementation to me (not counting the fact that if a string has the
> great misfortune to actually have a hash code of 0, the hash code will
> be recomputed every time hashCode() is called).
>
> Mainly, it's thread-safe not because any particularly increased care
> was taken in writing the method, but rather because the things that
> hashCode() relies on are not going to change after the class has been
> initialized, and so even if the "hash" value has been calculated in
> one thread but not yet visible in another, the worst that can happen
> is that it gets calculated again.
>
> I'd say that being immutable _does_ imply thread safety, even for
> lazily computed values. The only way that assumption would break is
> if the lazily computed values depends on something other than what's
> in the class itself, in which case I'd say the class is broken.
>
> I'm open to being proven wrong if someone has a counter-example.

public class SannyCode {
private final String s;
private boolean calculated = false;
private long code = 0;

public SannyCode(String s) {
this.s = s;
}

public long getCode() {
if (!calculated) {
calculated = true;
for (int i = s.length() - 1; i >= 0; i--) {
if (s.charAt(i) != '-') {
code += i;
}
}
}
return code;
}
}

Instances of SannyCode are immutable, in the context of a single
threaded application, but they are not thread-safe.

--
Jim Janney
From: Andreas Leitgeb on
Jim Janney <jjanney(a)shell.xmission.com> wrote:
> Peter Duniho <NpOeStPeAdM(a)NnOwSlPiAnMk.com> writes:
>> I mean sure, there are ways that it could have been written
>> incorrectly. The main (only?) non-thread-safe mistake being to use
>> the "hash" field itself as the accumulator for the calculation.
>
> public class SannyCode {
> [ uses the "hash" field itself as the accumulator for the calculation.]
> }

That's the one sin which Pete already mentioned.

But here is a "new" counter-example:
Use *anything thread-shared* as the accumulator.
(anything, but local vars and HashMap<Thread,*>-like stuff.)

Beyond that, the wording "use as the accumulator" could be addressed.