Re: Immutable or Effectively Immutable?

2014-05-16 Thread Gary Verhaegen
It will also see versions of any object or array referenced by those
final fields that are **at least as up-to-date as the final fields**
are.

To me this means that the value of the final field will be correctly
published **as of the time it was assigned**. So in your example,
there are two problems, I think:

* The modification that is done at the second line of the constructor
of Foo is **not**, in my understanding, safely published, since it is
more recent than the final field's assignment (reversing the two
lines *would*, in my understanding, safely publish the array, though
it would still not guarantee an ordering between the fill(1) and
fill(2) operations in this case);
* The value of the bytes array, when the second thread gets hold of
it, is not specified: the bytes variable itself is volatile, but not
its content, so the assignment to bytes must have occurred, but not
the filling with ones.

So, since the previous value of (the contents of) bytes is not
specified, and the next value of bytes is not safely published, in my
view, for this code, all bets are off as to the value seen by the
first thread on the match line. No combination of ones and twos
would surprise me (and I'm not even so sure about zeroes).

On 9 May 2014 17:41, Mike Fikes mikefi...@me.com wrote:
 Thanks Alexandru! That was insightful. :)

 Even the JLS's (non-normative?) text is confusing IMHO. Section 17.5 ends
 with this paragraph:

 The usage model for final fields is a simple one. Set the final fields for
 an object in that object's constructor. Do not write a reference to the
 object being constructed in a place where another thread can see it before
 the object's constructor is finished. If this is followed, then when the
 object is seen by another thread, that thread will always see the correctly
 constructed version of that object's final fields. It will also see versions
 of any object or array referenced by those final fields that are at least as
 up-to-date as the final fields are.

 If you read that paragraph, it would lead you to believe the bit in bold
 would be applicable to the program below. It seems that the key is, as you
 pointed out, simply extending the concept of this escaping to cover
 mutable references stored during construction.

 import java.util.Arrays;

 public class Main {

 static class Foo {
 final byte[] bytes;
 Foo(byte[] bytes) {
 this.bytes = bytes;
 Arrays.fill(this.bytes, (byte) 2);
 }
 }

 static volatile byte[] bytes;
 static volatile Foo foo;

 public static void main(String[] args) {

 new Thread(new Runnable() {
 public void run() {
 // Create an array filled with 1s and spin for other thread
 bytes = new byte[1024*1024];
 Arrays.fill(bytes, (byte) 1);
 while (foo == null) {}

 // Check to see if we get the array contents set by other
 thread
 byte[] expected = new byte[1024*1024];
 Arrays.fill(expected, (byte) 2);
 boolean match = Arrays.equals(expected, foo.bytes);
 System.out.println(match); // Will print false at times
 }
 }).start();

 new Thread(new Runnable() {
 public void run() {
 // Spin for first thread
 while (bytes == null) {}

 // Create an immutable object using bytes, while mutating
 bytes prior to construction completion and publication
 foo = new Foo(bytes);
 }
 }).start();
 }
 }


 On Thursday, May 8, 2014 4:43:10 PM UTC-4, Alexandru Nedelcu wrote:

 On Wed, May 7, 2014 at 6:31 AM, Alex Miller al...@puredanger.com wrote:

 It does matter with regard to visibility across threads - your example
 does not use a synchronization mechanism and there is no guarantee that
 other threads will ever see those changes (so don't ever ever do that :).
 But if you stick to the normal Clojure apis, all is good. I'd highly
 recommend reading JCIP to dive into the details.

 Final field freeze is particularly weird and it baked my noodle when I
 first encountered it - here's a blog I wrote about it approx 697 years ago
 in internet time (and Brian Goetz backs me up in the comments :)
 http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/

 I believe that while JCIP is useful, it is also confusing, because it is
 trying to explain Java’s memory model in layman’s terms. I recently
 experienced “enlightenment”, by making an effort to understand how things
 work at a lower level.

 Happens-before relationships / ordering guarantees are given by the
 compiler, in combination with the CPU, with the rules being implied by usage
 of memory fences (barriers). Without ordering guarantees, several things can
 happen - the compiler could optimize the code by reordering or eliminating
 instructions, the CPU might optimize the code 

Re: Immutable or Effectively Immutable?

2014-05-16 Thread Stuart Halloway
;; I think this shed should be painted red
(def immutable-string
  foo)

(def ^java.lang.reflect.Field value-field
  (doto (.getDeclaredField String value)
(.setAccessible true)))

(aset (.get value-field immutable-string) 1 \i)
(aset (.get value-field immutable-string) 2 \e)

(println immutable-string)



On Wed, May 7, 2014 at 11:15 AM, Mike Fikes mikefi...@me.com wrote:

 I would offer that the key distinction is whether final is used: This
 prescribes what you must do when using the object.

 Take Date for example. You can't just pass one directly from one thread
 to another. The receiving thread could read a date associated with
 System.currentTimeMillis() of 0.

 But, String, since it uses final on its char[], fundamentally changes
 this. (If the final keyword were not present in String, even though you
 have no way to change its char[], it would be broken with respect to
 threading semantics.)

 On Wednesday, May 7, 2014 10:35:04 AM UTC-4, Andy Fingerhut wrote:

 Sorry if I'm beating a dead horse here.

 I agree that my example is not using published Clojure APIs, and I never
 do that kind of thing in a Clojure program, except as an example that
 PersistentVector's are mutable if you use Java APIs instead of restricting
 yourself to Clojure APIs.  You don't even need to use reflection in Java or
 know about JVM security policies to mutate them (I am not suggesting that
 Clojure should be changed in any way here).

 I've actually got a copy of Java: Concurrency in Practice, and looked up
 (some of) what they say about immutability.  Here is one definition they
 give of immutability, with some preceding text.  I have added emphasis to
 one phrase:

 Neither the Java Language Specification nor the Java Memory Model
 formally defines immutability, but __immutability is *not* equivalent to
 simply declaring all fields of an object 'final'__.  An object whose fields
 are all final may still be mutable, since final fields can hold references
 to mutable objects.

 An object is *immutable* if:
 + Its state cannot be modified after construction;
 + All its fields are 'final'; and
 + It is *properly constructed* (the 'this' reference does not escape
 during construction).

 I have no argument with PersistentVector satisfying the 2nd and 3rd
 bullet points above, but (1) seems not to hold.  According to JCIP's
 definition of effectively immutable (Objects that are not technically
 immutable, but whose state will not be modified after publication),
 PersistentVector appears to me to be effectively immutable, but not truly
 immutable.

 Andy


 On Tue, May 6, 2014 at 8:31 PM, Alex Miller al...@puredanger.com wrote:

 Hey Andy,

 It does matter with regard to visibility across threads - your example
 does not use a synchronization mechanism and there is no guarantee that
 other threads will ever see those changes (so don't ever ever do that :).
 But if you stick to the normal Clojure apis, all is good. I'd highly
 recommend reading JCIP to dive into the details.

 Final field freeze is particularly weird and it baked my noodle when I
 first encountered it - here's a blog I wrote about it approx 697 years ago
 in internet time (and Brian Goetz backs me up in the comments :)
 http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/

 Alex


 On Tuesday, May 6, 2014 7:35:43 PM UTC-5, Andy Fingerhut wrote:

 Alex, I may be unfamiliar with the definitions of truly immutable and
 effectively immutable being used here, but if I can mutate the contents of
 a Java Object array that is a final field after an object is constructed,
 does it really matter that much if it is final?  It is trivially easy to
 mutate using Java access.  Here is the example that I mentioned earlier in
 this thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller al...@puredanger.comwrote:

  The Clojure persistent data structures are truly immutable - all
 fields are final and referred objects are not mutated after construction 
 so
 that freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang -
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly
 immutable (using final fields, relying on constructor freezing), or are
 they mean to be merely effectively immutable (as defined in JICP)?

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com

 Note that posts from new members are moderated - please be patient
 with your first post.
 To unsubscribe from this group, send email to
 clojure+u

Re: Immutable or Effectively Immutable?

2014-05-16 Thread Mike Fikes
In the sample code I pasted, there is nothing to prevent the fill(1) and 
fill(2) from running concurrently, and essentially write into the same array 
concurrently. My intent was that the fill(1) be complete before the second 
thread proceeds.

A simple change to have the 1st thread instead fill a temporary byte[] followed 
by assigning the temporary reference to the static volatile byte[] causes the 
program to no longer print “false”. 

This behavior, while it doesn't prove anything, is consistent with the JLS 
paragraph I quoted.

But, it doesn't disprove Alexandru's claim either...

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-09 Thread Phillip Lord
Alexandru Nedelcu a...@bionicspirit.com writes:
 On Wed, May 7, 2014 at 5:57 PM, Phillip Lord
 phillip.l...@newcastle.ac.ukwrote:

 In general, though, if I write some code like

 (if (instance? Cons x)
 (pass-to-another-thread-without-synchronisation x))

 I cannot guarantee the result of this because although I know that
 the head of x is fixed, I cannot guarantee that for the tail. If I know
 how x is constructed, of course, then I can make this guarantee.


 On the other hand, that's not the concern of the piece of code you
 outlined. Because if x wasn't constructed properly and the latest data
 in it is not visible, there's absolutely nothing you can do about it ;-)
 Visibility is (or should be) the concern of the producer, not of the
 consumer.


Perhaps I didn't word this well. The problem is with my code is that I
only know about the implementation of the head of x. When I talk about
construction, I mean, if I know what else is in x. Not clear, sorry!




 You get the a related problem in Java.

 List l = Collections.unmodifiedableList(l);

 Is l now unmodifiable? Well maybe, depending on what happened to it
 before.


 What happened to it before is not relevant, because again, there's
 nothing you can do about it at this point and actually from this consumer's
 perspective before doesn't exist ... there's only now with the only
 question being if there are or there will be pending changes that may or
 may not be published in the future (where future is kind of thread-local).

Again, not great wording. l is unmodifiable if it's not be let out
anywhere. That's the problem. The reason it's related to the issue in
Clojure is that, List is an interface, while Cons is build in terms of
an interface. You cannot define immutability (or unmodifiability) in
terms of an abstract interface.

Java String are immutable. Concrete and final implementation.



 Concurrency is hard, but it's greatly simplified if you keep the concerns
 for atomicity and visibility on the producer's side.

Not going to disagree with this. I just answered the original question
is all:-)

Phil

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-09 Thread Mike Fikes


Thanks Alexandru! That was insightful. :)

Even the JLS's (non-normative?) text is confusing IMHO. Section 17.5 ends 
with this paragraph:

The usage model for final fields is a simple one. Set the final fields for 
an object in that object's constructor. Do not write a reference to the 
object being constructed in a place where another thread can see it before 
the object's constructor is finished. If this is followed, then when the 
object is seen by another thread, that thread will always see the correctly 
constructed version of that object's final fields. *It will also see 
versions of any object or array referenced by those final fields that are 
at least as up-to-date as the final fields are.*

If you read that paragraph, it would lead you to believe the bit in bold 
would be applicable to the program below. It seems that the key is, as you 
pointed out, simply extending the concept of this escaping to cover 
mutable references stored during construction.

import java.util.Arrays;

public class Main {

static class Foo {
final byte[] bytes;
Foo(byte[] bytes) {
this.bytes = bytes;
Arrays.fill(this.bytes, (byte) 2);
}
}

static volatile byte[] bytes;
static volatile Foo foo;

public static void main(String[] args) {

new Thread(new Runnable() {
public void run() {
// Create an array filled with 1s and spin for other thread
bytes = new byte[1024*1024];
Arrays.fill(bytes, (byte) 1);
while (foo == null) {}

// Check to see if we get the array contents set by other thread
byte[] expected = new byte[1024*1024];
Arrays.fill(expected, (byte) 2);
boolean match = Arrays.equals(expected, foo.bytes);
System.out.println(match); // Will print false at times
}
}).start();

new Thread(new Runnable() {
public void run() {
// Spin for first thread
while (bytes == null) {}

// Create an immutable object using bytes, while mutating 
bytes prior to construction completion and publication
foo = new Foo(bytes);
}
}).start();
}
}


On Thursday, May 8, 2014 4:43:10 PM UTC-4, Alexandru Nedelcu wrote:

 On Wed, May 7, 2014 at 6:31 AM, Alex Miller 
 al...@puredanger.comjavascript: 
 wrote:

 It does matter with regard to visibility across threads - your example 
 does not use a synchronization mechanism and there is no guarantee that 
 other threads will ever see those changes (so don't ever ever do that :). 
 But if you stick to the normal Clojure apis, all is good. I'd highly 
 recommend reading JCIP to dive into the details. 

 Final field freeze is particularly weird and it baked my noodle when I 
 first encountered it - here's a blog I wrote about it approx 697 years ago 
 in internet time (and Brian Goetz backs me up in the comments :)
 http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/

  I believe that while JCIP is useful, it is also confusing, because it is 
 trying to explain Java’s memory model in layman’s terms. I recently 
 experienced “enlightenment”, by making an effort to understand how things 
 work at a lower level. 

 Happens-before relationships / ordering guarantees are given by the 
 compiler, in combination with the CPU, with the rules being implied by 
 usage of memory fences (barriers). Without ordering guarantees, several 
 things can happen - the compiler could optimize the code by reordering or 
 eliminating instructions, the CPU might optimize the code by reordering or 
 eliminating instructions and - what bits beginners the most - today’s 
 multi-core CPUs are tricky, as each CPU has a store buffer that’s local to 
 each core (i.e. other cores cannot see it) and published values only become 
 visible to other cores when the store buffer gets flushed to the L1 cache. 
 And you have no guarantee that this flush will *ever* happen, or even 
 after it happens, you have no guarantee that other processors that already 
 have a cached value will make an effort to read the more up-to-date value … 
 unless ordering semantics are enforced. And actually thinking in terms of 
 flushes to memory is dangerous, as nothing you do guarantees a flush - 
 everything being relative, specified in terms of happens-before 
 relationships, implied by memory barriers.

 And memory barriers are tricky beasts, as they come in multiple shapes and 
 sizes. The JSR 133 Cookbookhttp://gee.cs.oswego.edu/dl/jmm/cookbook.htmlis 
 a useful document for shedding some light on how they work. In 
 particular, for final fields, you get a guarantee for a *StoreStore*memory 
 barrier, like so:

 x.finalField = v; *StoreStore*; sharedRef = x;

 This guarantee basically says that the finalFields’ value will always be 
 stored before the write sharedRef 

Re: Immutable or Effectively Immutable?

2014-05-08 Thread Alexandru Nedelcu
On Wed, May 7, 2014 at 6:31 AM, Alex Miller a...@puredanger.com wrote:

It does matter with regard to visibility across threads - your example does
 not use a synchronization mechanism and there is no guarantee that other
 threads will ever see those changes (so don't ever ever do that :). But if
 you stick to the normal Clojure apis, all is good. I'd highly recommend
 reading JCIP to dive into the details.

 Final field freeze is particularly weird and it baked my noodle when I
 first encountered it - here's a blog I wrote about it approx 697 years ago
 in internet time (and Brian Goetz backs me up in the comments :)
 http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/

 I believe that while JCIP is useful, it is also confusing, because it is
trying to explain Java’s memory model in layman’s terms. I recently
experienced “enlightenment”, by making an effort to understand how things
work at a lower level.

Happens-before relationships / ordering guarantees are given by the
compiler, in combination with the CPU, with the rules being implied by
usage of memory fences (barriers). Without ordering guarantees, several
things can happen - the compiler could optimize the code by reordering or
eliminating instructions, the CPU might optimize the code by reordering or
eliminating instructions and - what bits beginners the most - today’s
multi-core CPUs are tricky, as each CPU has a store buffer that’s local to
each core (i.e. other cores cannot see it) and published values only become
visible to other cores when the store buffer gets flushed to the L1 cache.
And you have no guarantee that this flush will *ever* happen, or even after
it happens, you have no guarantee that other processors that already have a
cached value will make an effort to read the more up-to-date value … unless
ordering semantics are enforced. And actually thinking in terms of flushes
to memory is dangerous, as nothing you do guarantees a flush - everything
being relative, specified in terms of happens-before relationships, implied
by memory barriers.

And memory barriers are tricky beasts, as they come in multiple shapes and
sizes. The JSR 133 Cookbook
http://gee.cs.oswego.edu/dl/jmm/cookbook.htmlis a useful document
for shedding some light on how they work. In
particular, for final fields, you get a guarantee for a *StoreStore* memory
barrier, like so:

x.finalField = v; *StoreStore*; sharedRef = x;

This guarantee basically says that the finalFields’ value will always be
stored before the write sharedRef = x happens. Or in other words, once the
constructor of x is finished and the value stored inside a sharedRef, the
finals are already fully initialized. And this extends to whatever writes
that happened in the object stored in that final field too. This assumes
that this didn’t escape during construction - in which case the above
guarantee becomes meaningless for threads that already saw object x. As an
aside, a StoreStore fence on X86 is a no-op, as stores on X86 are ordered,
but for other processors this is not true and the compiler can and does
reorder instructions by itself.

Also consider doing something like:

 final int[] field = new int[] {1,2,3,4}

Even though that array is not immutable, the array and the values in it
will be visible once the final field itself becomes visible, again because
of the store ordering guarantee. But this doesn’t hold if that array
reference has been seen before, so this doesn’t work as people might think:

final int[] field;
public Constructor(int[] arr) { field = arr }

My initial impression was that a final field store behaves like a volatile
write. That’s not true. A volatile write is *preceded* by a StoreStore,
while a final write is succeeded by one. Also, a volatile write followed by
a volatile read guarantees a Store/Load memory barrier between the two
actions for ordering previous stores with subsequent loads - this is the
rule that says that once a volatile is stored, then subsequent reads are
ordered after that store (so the volatile read is basically monitor enter
and the volatile write is basically monitor exit … the similarity with
acquiring locks is not accidental at all) and so threads don’t get stale
data. Finals don’t get the same treatment, even though there are
similarities between the two … this is also why it is important for this to
not escape during construction or for why the array reference received from
the outside in the above won’t necessarily be up-to-date when the final
will be observed by other threads - again, ordering guarantees are relative.

In other words, for finals to work properly, this mustn’t escape during
construction and care must be taken when storing references to mutable
things received from the outside.
-- 
Alexandru Nedelcu
www.bionicspirit.com

PGP Public Key:
https://bionicspirit.com/key.aexpk

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to 

Re: Immutable or Effectively Immutable?

2014-05-08 Thread Alexandru Nedelcu
On Wed, May 7, 2014 at 5:57 PM, Phillip Lord
phillip.l...@newcastle.ac.ukwrote:

 In general, though, if I write some code like

 (if (instance? Cons x)
 (pass-to-another-thread-without-synchronisation x))

 I cannot guarantee the result of this because although I know that
 the head of x is fixed, I cannot guarantee that for the tail. If I know
 how x is constructed, of course, then I can make this guarantee.


On the other hand, that's not the concern of the piece of code you
outlined. Because if x wasn't constructed properly and the latest data
in it is not visible, there's absolutely nothing you can do about it ;-)
Visibility is (or should be) the concern of the producer, not of the
consumer.


 You get the a related problem in Java.

 List l = Collections.unmodifiedableList(l);

 Is l now unmodifiable? Well maybe, depending on what happened to it
 before.


What happened to it before is not relevant, because again, there's
nothing you can do about it at this point and actually from this consumer's
perspective before doesn't exist ... there's only now with the only
question being if there are or there will be pending changes that may or
may not be published in the future (where future is kind of thread-local).

Concurrency is hard, but it's greatly simplified if you keep the concerns
for atomicity and visibility on the producer's side. And if some
third-party module or function or class or whatever doesn't respect this
rule by delegating such concerns to the consumer, then simply scrap it from
the code-base if it's such a big deal - Date is mutable and that's a
problem? Use Joda, etc... Java libraries also document when something is
thread-safe and if that's left unspecified, it means that it isn't.

That's how people working with C++ also keep their sanity in regards to
memory management - i.e. when a producer passes along a pointer or
reference of something to a consumer, the sanest thing to do is to consider
deallocation or other life cycle issues as the responsibility of the
producer, unless it's very explicit in the exposed API that the consumer
should handle it.

-- 
Alexandru Nedelcu
www.bionicspirit.com

PGP Public Key:
https://bionicspirit.com/key.aexpk

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-07 Thread Phillip Lord

Since the data structures and interfaces, they are effectively
immutable.

Consider this:

final public class Cons extends ASeq implements Serializable {

private final Object _first;
private final ISeq _more;

public Cons(Object first, ISeq _more){
this._first = first;
this._more = _more;
}
}

Although Cons uses final fields and constructor fields, _more is an
ISeq; given that this could be mutable, so could cons.

Phil

Mike Fikes mikefi...@me.com writes:

 Are the persistent immutable data structures in Clojure truly immutable 
 (using final fields, relying on constructor freezing), or are they mean to 
 be merely effectively immutable (as defined in JICP)?

-- 
Phillip Lord,   Phone: +44 (0) 191 222 7827
Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk
School of Computing Science,
http://homepages.cs.ncl.ac.uk/phillip.lord
Room 914 Claremont Tower,   skype: russet_apples
Newcastle University,   twitter: phillord
NE1 7RU 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-07 Thread Andy Fingerhut
Mike, I believe I understand the definition of truly immutable you are
using here, and what it means in the JVM as far as synchronization of
object values across threads.

What seems a bit odd is to use the phrase truly immutable to describe
something that is clearly mutable, or at least it is by the definition of
mutable: can be modified after construction, which PersistentVector and
others can be.

Thanks,
Andy


On Tue, May 6, 2014 at 6:20 PM, Mike Fikes mikefi...@me.com wrote:

 Hi Andy,

 Marking Java fields as final has semantics with respect to threading,
 defined in the JLS in section 17.5 (
 http://docs.oracle.com/javase/specs/jls/se5.0/html/memory.html#17.5)

 If you do this, then it makes it possible to freely pass a truly
 immutable object instance to another thread and be guaranteed that that
 other thread will see the value initialized for that field in the
 constructor.

 If you don't do this, then the object can still be effectively
 immutable, which essentially means that you can pass the object to another
 thread, so long as you do it in a safe manner (using a volatile, or some
 synchronization mechanism).

 JCIP helps clarify all of this unfortunately complex topic.

 The important thing (and key to Closure), is that, if you are implementing
 the class that you want to be immutable, then if you can mark everything as
 final, then you truly achieve the benefits immutability give you with
 concurrency (in short, you need no synchronization whatsoever). If you fail
 to do this, then you have effective immutability, which is good, but
 complex and comes with caveats on how you can safely pass objects between
 threads.

 JCIP is a great book. But, the approach taken by Clojure makes a lot of
 the complicated concerns covered by the book largely ignorable, IMHO.

 On Tuesday, May 6, 2014 8:35:43 PM UTC-4, Andy Fingerhut wrote:

 Alex, I may be unfamiliar with the definitions of truly immutable and
 effectively immutable being used here, but if I can mutate the contents of
 a Java Object array that is a final field after an object is constructed,
 does it really matter that much if it is final?  It is trivially easy to
 mutate using Java access.  Here is the example that I mentioned earlier in
 this thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller al...@puredanger.com wrote:

 The Clojure persistent data structures are truly immutable - all fields
 are final and referred objects are not mutated after construction so that
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang -
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly
 immutable (using final fields, relying on constructor freezing), or are
 they mean to be merely effectively immutable (as defined in JICP)?

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com

 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received

Re: Immutable or Effectively Immutable?

2014-05-07 Thread Andy Fingerhut
Sorry if I'm beating a dead horse here.

I agree that my example is not using published Clojure APIs, and I never do
that kind of thing in a Clojure program, except as an example that
PersistentVector's are mutable if you use Java APIs instead of restricting
yourself to Clojure APIs.  You don't even need to use reflection in Java or
know about JVM security policies to mutate them (I am not suggesting that
Clojure should be changed in any way here).

I've actually got a copy of Java: Concurrency in Practice, and looked up
(some of) what they say about immutability.  Here is one definition they
give of immutability, with some preceding text.  I have added emphasis to
one phrase:

Neither the Java Language Specification nor the Java Memory Model formally
defines immutability, but __immutability is *not* equivalent to simply
declaring all fields of an object 'final'__.  An object whose fields are
all final may still be mutable, since final fields can hold references to
mutable objects.

An object is *immutable* if:
+ Its state cannot be modified after construction;
+ All its fields are 'final'; and
+ It is *properly constructed* (the 'this' reference does not escape
during construction).

I have no argument with PersistentVector satisfying the 2nd and 3rd bullet
points above, but (1) seems not to hold.  According to JCIP's definition of
effectively immutable (Objects that are not technically immutable, but
whose state will not be modified after publication), PersistentVector
appears to me to be effectively immutable, but not truly immutable.

Andy


On Tue, May 6, 2014 at 8:31 PM, Alex Miller a...@puredanger.com wrote:

 Hey Andy,

 It does matter with regard to visibility across threads - your example
 does not use a synchronization mechanism and there is no guarantee that
 other threads will ever see those changes (so don't ever ever do that :).
 But if you stick to the normal Clojure apis, all is good. I'd highly
 recommend reading JCIP to dive into the details.

 Final field freeze is particularly weird and it baked my noodle when I
 first encountered it - here's a blog I wrote about it approx 697 years ago
 in internet time (and Brian Goetz backs me up in the comments :)
 http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/

 Alex


 On Tuesday, May 6, 2014 7:35:43 PM UTC-5, Andy Fingerhut wrote:

 Alex, I may be unfamiliar with the definitions of truly immutable and
 effectively immutable being used here, but if I can mutate the contents of
 a Java Object array that is a final field after an object is constructed,
 does it really matter that much if it is final?  It is trivially easy to
 mutate using Java access.  Here is the example that I mentioned earlier in
 this thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller al...@puredanger.com wrote:

 The Clojure persistent data structures are truly immutable - all fields
 are final and referred objects are not mutated after construction so that
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang -
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly
 immutable (using final fields, relying on constructor freezing), or are
 they mean to be merely effectively immutable (as defined in JICP)?

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com

 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com

Re: Immutable or Effectively Immutable?

2014-05-07 Thread Mike Fikes
Phil, that's an interesting point.

Consider (def x (cons (new java.util.Date) ()))

The object identified by x is *mutable*, but if the contained Date will not 
be modified by the program, then the resulting object can be treated as 
*effectively 
immutable, *as you pointed out.

But, it would seem that you could pass x to another thread without 
synchronization, and then safely read the contained Date instance by that 
thread, because it has been safely published by virtue of having been 
conveyed by a final field of the Cons instance. Of course, you would run 
into trouble if you took that Date instance and passed it directly to 
another thread without synchronization.

In other words, you could step outside of the limited profile of the Java 
memory model that JCIP prescribes treating x as something (useful) between 
*effectively 
immutable *and *immutable, *with the end result being that you can treat x as 
being *immutable.*

On Wednesday, May 7, 2014 7:13:31 AM UTC-4, Phillip Lord wrote:


 Since the data structures and interfaces, they are effectively 
 immutable. 

 Consider this: 

 final public class Cons extends ASeq implements Serializable { 

 private final Object _first; 
 private final ISeq _more; 

 public Cons(Object first, ISeq _more){ 
 this._first = first; 
 this._more = _more; 
 } 
 } 

 Although Cons uses final fields and constructor fields, _more is an 
 ISeq; given that this could be mutable, so could cons. 

 Phil 

 Mike Fikes mike...@me.com javascript: writes: 

  Are the persistent immutable data structures in Clojure truly 
 immutable 
  (using final fields, relying on constructor freezing), or are they mean 
 to 
  be merely effectively immutable (as defined in JICP)? 

 -- 
 Phillip Lord,   Phone: +44 (0) 191 222 7827 
 Lecturer in Bioinformatics, Email: 
 philli...@newcastle.ac.ukjavascript: 
 School of Computing Science,
 http://homepages.cs.ncl.ac.uk/phillip.lord 
 Room 914 Claremont Tower,   skype: russet_apples 
 Newcastle University,   twitter: phillord 
 NE1 7RU 


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-07 Thread Mike Fikes
Yep. PersistentVector is *mutable* per the JCIP definition.

If it is *mutable* then you need to use locks or synchronization to access 
its contents.

If your program doesn't modify its the vector, it is *effectively 
immutable. *But, you need to ensure that you safely publish it.

But, if you create a PersistentVector, and somehow ensure that the array's 
contents are never modified, you can pass it freely between threads without 
synchronization.

In short, even though you can't claim that PersistentVector is *immutable*, 
if you discipline yourself on how you use it, you can pretend that it is.

This is a consequence of the use of final on the array field in 
PersistentVector.

On Wednesday, May 7, 2014 10:17:38 AM UTC-4, Andy Fingerhut wrote:

 Mike, I believe I understand the definition of truly immutable you are 
 using here, and what it means in the JVM as far as synchronization of 
 object values across threads.

 What seems a bit odd is to use the phrase truly immutable to describe 
 something that is clearly mutable, or at least it is by the definition of 
 mutable: can be modified after construction, which PersistentVector and 
 others can be.

 Thanks,
 Andy


 On Tue, May 6, 2014 at 6:20 PM, Mike Fikes mike...@me.com 
 javascript:wrote:

 Hi Andy,

 Marking Java fields as final has semantics with respect to threading, 
 defined in the JLS in section 17.5 (
 http://docs.oracle.com/javase/specs/jls/se5.0/html/memory.html#17.5)

 If you do this, then it makes it possible to freely pass a truly 
 immutable object instance to another thread and be guaranteed that that 
 other thread will see the value initialized for that field in the 
 constructor.

 If you don't do this, then the object can still be effectively 
 immutable, which essentially means that you can pass the object to another 
 thread, so long as you do it in a safe manner (using a volatile, or some 
 synchronization mechanism).

 JCIP helps clarify all of this unfortunately complex topic.

 The important thing (and key to Closure), is that, if you are 
 implementing the class that you want to be immutable, then if you can mark 
 everything as final, then you truly achieve the benefits immutability give 
 you with concurrency (in short, you need no synchronization whatsoever). If 
 you fail to do this, then you have effective immutability, which is good, 
 but complex and comes with caveats on how you can safely pass objects 
 between threads.

 JCIP is a great book. But, the approach taken by Clojure makes a lot of 
 the complicated concerns covered by the book largely ignorable, IMHO.

 On Tuesday, May 6, 2014 8:35:43 PM UTC-4, Andy Fingerhut wrote:

 Alex, I may be unfamiliar with the definitions of truly immutable and 
 effectively immutable being used here, but if I can mutate the contents of 
 a Java Object array that is a final field after an object is constructed, 
 does it really matter that much if it is final?  It is trivially easy to 
 mutate using Java access.  Here is the example that I mentioned earlier in 
 this thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller al...@puredanger.comwrote:

  The Clojure persistent data structures are truly immutable - all 
 fields are final and referred objects are not mutated after construction 
 so 
 that freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in 
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - 
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly 
 immutable (using final fields, relying on constructor freezing), or are 
 they mean to be merely effectively immutable (as defined in JICP)?

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com

 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google 
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send 
 an email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.comjavascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u

Re: Immutable or Effectively Immutable?

2014-05-07 Thread Mike Fikes
I would offer that the key distinction is whether final is used: This 
prescribes what you must do when using the object.

Take Date for example. You can't just pass one directly from one thread to 
another. The receiving thread could read a date associated with 
System.currentTimeMillis() of 0. 

But, String, since it uses final on its char[], fundamentally changes this. 
(If the final keyword were not present in String, even though you have no 
way to change its char[], it would be broken with respect to threading 
semantics.)

On Wednesday, May 7, 2014 10:35:04 AM UTC-4, Andy Fingerhut wrote:

 Sorry if I'm beating a dead horse here.

 I agree that my example is not using published Clojure APIs, and I never 
 do that kind of thing in a Clojure program, except as an example that 
 PersistentVector's are mutable if you use Java APIs instead of restricting 
 yourself to Clojure APIs.  You don't even need to use reflection in Java or 
 know about JVM security policies to mutate them (I am not suggesting that 
 Clojure should be changed in any way here).

 I've actually got a copy of Java: Concurrency in Practice, and looked up 
 (some of) what they say about immutability.  Here is one definition they 
 give of immutability, with some preceding text.  I have added emphasis to 
 one phrase:

 Neither the Java Language Specification nor the Java Memory Model 
 formally defines immutability, but __immutability is *not* equivalent to 
 simply declaring all fields of an object 'final'__.  An object whose fields 
 are all final may still be mutable, since final fields can hold references 
 to mutable objects.

 An object is *immutable* if:
 + Its state cannot be modified after construction;
 + All its fields are 'final'; and
 + It is *properly constructed* (the 'this' reference does not escape 
 during construction).

 I have no argument with PersistentVector satisfying the 2nd and 3rd bullet 
 points above, but (1) seems not to hold.  According to JCIP's definition of 
 effectively immutable (Objects that are not technically immutable, but 
 whose state will not be modified after publication), PersistentVector 
 appears to me to be effectively immutable, but not truly immutable.

 Andy


 On Tue, May 6, 2014 at 8:31 PM, Alex Miller al...@puredanger.comjavascript:
  wrote:

 Hey Andy,

 It does matter with regard to visibility across threads - your example 
 does not use a synchronization mechanism and there is no guarantee that 
 other threads will ever see those changes (so don't ever ever do that :). 
 But if you stick to the normal Clojure apis, all is good. I'd highly 
 recommend reading JCIP to dive into the details. 

 Final field freeze is particularly weird and it baked my noodle when I 
 first encountered it - here's a blog I wrote about it approx 697 years ago 
 in internet time (and Brian Goetz backs me up in the comments :)
 http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/

 Alex


 On Tuesday, May 6, 2014 7:35:43 PM UTC-5, Andy Fingerhut wrote:

 Alex, I may be unfamiliar with the definitions of truly immutable and 
 effectively immutable being used here, but if I can mutate the contents of 
 a Java Object array that is a final field after an object is constructed, 
 does it really matter that much if it is final?  It is trivially easy to 
 mutate using Java access.  Here is the example that I mentioned earlier in 
 this thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller al...@puredanger.comwrote:

  The Clojure persistent data structures are truly immutable - all 
 fields are final and referred objects are not mutated after construction 
 so 
 that freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in 
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - 
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly 
 immutable (using final fields, relying on constructor freezing), or are 
 they mean to be merely effectively immutable (as defined in JICP)?

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com

 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google 
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send 
 an email to clojure+u...@googlegroups.com.

 For more options

Immutable or Effectively Immutable?

2014-05-06 Thread Mike Fikes
Are the persistent immutable data structures in Clojure truly immutable 
(using final fields, relying on constructor freezing), or are they mean to 
be merely effectively immutable (as defined in JICP)?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Andy Fingerhut
I haven't read JICP that you refer to, but I believe that they are
effectively immutable.

See a post by me in this thread titled Clojure Concurrency and Custom
Types from March 2013 for how to stay within Clojure, but I believe
requiring Java interop calls, to mutate in place Clojure's immutable data
structures:


https://mail.google.com/mail/u/0/#search/label%3Aclojure+concurrency+and+custom+types/13d9d40bc9dd658a

I have never seen code like that in any Clojure libraries I have looked at,
though.

Andy


On Tue, May 6, 2014 at 2:11 PM, Mike Fikes mikefi...@me.com wrote:

 Are the persistent immutable data structures in Clojure truly immutable
 (using final fields, relying on constructor freezing), or are they mean to
 be merely effectively immutable (as defined in JICP)?

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Alex Miller
The Clojure persistent data structures are truly immutable - all fields are 
final and referred objects are not mutated after construction so that 
freeze occurs.  One obvious exception are the transient variants 
(http://clojure.org/transients). You can look at the code 
in https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - 
any of the Persistent*.java.

On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly immutable 
 (using final fields, relying on constructor freezing), or are they mean to 
 be merely effectively immutable (as defined in JICP)?


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Timothy Baldridge
And hash codes are not final as they are calculated on-the-fly on most of
the Clojure data structures.

Timothy


On Tue, May 6, 2014 at 5:49 PM, Alex Miller a...@puredanger.com wrote:

 The Clojure persistent data structures are truly immutable - all fields
 are final and referred objects are not mutated after construction so that
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - any
 of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly immutable
 (using final fields, relying on constructor freezing), or are they mean to
 be merely effectively immutable (as defined in JICP)?

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Andy Fingerhut
Alex, I may be unfamiliar with the definitions of truly immutable and
effectively immutable being used here, but if I can mutate the contents of
a Java Object array that is a final field after an object is constructed,
does it really matter that much if it is final?  It is trivially easy to
mutate using Java access.  Here is the example that I mentioned earlier in
this thread, copied here for convenience:

user= (def v [1 2 3])
#'user/v
user= (class v)
clojure.lang.PersistentVector
user= v
[1 2 3]
user= (aset (.tail v) 1 -2)
-2
user= v
[1 -2 3]

Andy


On Tue, May 6, 2014 at 4:49 PM, Alex Miller a...@puredanger.com wrote:

 The Clojure persistent data structures are truly immutable - all fields
 are final and referred objects are not mutated after construction so that
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - any
 of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly immutable
 (using final fields, relying on constructor freezing), or are they mean to
 be merely effectively immutable (as defined in JICP)?

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Michał Marczyk
vec with a short array of objects is a special case in that it simply
puts the existing array in a PersistentVector wrapper:

user= (def arr (object-array 16))
#'user/arr
user= (doseq [i (range 16)] (aset arr i i))
nil
user= (def v (vec arr))
#'user/v
user= v
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
user= (aset arr 0 :foo)
:foo
user= v
[:foo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]

This works for up to 32 objects, as that is the number that fits in a PV tail.

No member access syntax here -- not sure if object-array/aset count as interop.

NB. vec's docstring is explicit about this.


On 7 May 2014 02:35, Andy Fingerhut andy.finger...@gmail.com wrote:
 Alex, I may be unfamiliar with the definitions of truly immutable and
 effectively immutable being used here, but if I can mutate the contents of a
 Java Object array that is a final field after an object is constructed, does
 it really matter that much if it is final?  It is trivially easy to mutate
 using Java access.  Here is the example that I mentioned earlier in this
 thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller a...@puredanger.com wrote:

 The Clojure persistent data structures are truly immutable - all fields
 are final and referred objects are not mutated after construction so that
 freeze occurs.  One obvious exception are the transient variants
 (http://clojure.org/transients). You can look at the code in
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - any of
 the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly immutable
 (using final fields, relying on constructor freezing), or are they mean to
 be merely effectively immutable (as defined in JICP)?

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Mike Fikes
Hi Andy,

Marking Java fields as final has semantics with respect to threading, 
defined in the JLS in section 17.5 
(http://docs.oracle.com/javase/specs/jls/se5.0/html/memory.html#17.5)

If you do this, then it makes it possible to freely pass a truly 
immutable object instance to another thread and be guaranteed that that 
other thread will see the value initialized for that field in the 
constructor.

If you don't do this, then the object can still be effectively immutable, 
which essentially means that you can pass the object to another thread, so 
long as you do it in a safe manner (using a volatile, or some 
synchronization mechanism).

JCIP helps clarify all of this unfortunately complex topic.

The important thing (and key to Closure), is that, if you are implementing 
the class that you want to be immutable, then if you can mark everything as 
final, then you truly achieve the benefits immutability give you with 
concurrency (in short, you need no synchronization whatsoever). If you fail 
to do this, then you have effective immutability, which is good, but 
complex and comes with caveats on how you can safely pass objects between 
threads.

JCIP is a great book. But, the approach taken by Clojure makes a lot of the 
complicated concerns covered by the book largely ignorable, IMHO.

On Tuesday, May 6, 2014 8:35:43 PM UTC-4, Andy Fingerhut wrote:

 Alex, I may be unfamiliar with the definitions of truly immutable and 
 effectively immutable being used here, but if I can mutate the contents of 
 a Java Object array that is a final field after an object is constructed, 
 does it really matter that much if it is final?  It is trivially easy to 
 mutate using Java access.  Here is the example that I mentioned earlier in 
 this thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller al...@puredanger.comjavascript:
  wrote:

 The Clojure persistent data structures are truly immutable - all fields 
 are final and referred objects are not mutated after construction so that 
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in 
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - 
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly 
 immutable (using final fields, relying on constructor freezing), or are 
 they mean to be merely effectively immutable (as defined in JICP)?

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.comjavascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Mike Fikes
Thanks!

I initially saw that the count field of ArrayNode (in PersistentHashMap) is 
non-final and also mutated in at least one case, and began to question 
things.

But, for that particular example, if that field is only mutated in the case 
of editing transients, then for the non-transient case ArrayNode is 
effectively immutable but also safely published by any truly immutable data 
structures by being referred to in final fields.

Excellent! I had to look for myself, and now I feel much more comfortable 
that Clojure is built upon the bedrock it needs to be :)

On Tuesday, May 6, 2014 7:49:07 PM UTC-4, Alex Miller wrote:

 The Clojure persistent data structures are truly immutable - all fields 
 are final and referred objects are not mutated after construction so that 
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in 
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - any 
 of the Persistent*.java.

 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly immutable 
 (using final fields, relying on constructor freezing), or are they mean to 
 be merely effectively immutable (as defined in JICP)?



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Alex Miller
Yes, there may be a few special cases out there, but largely around 
transients. The transient case constrains the mutability to a thread so 
still simplifies the concurrency safety story immensely.

On Tuesday, May 6, 2014 8:44:53 PM UTC-5, Mike Fikes wrote:

 Thanks!

 I initially saw that the count field of ArrayNode (in PersistentHashMap) 
 is non-final and also mutated in at least one case, and began to question 
 things.

 But, for that particular example, if that field is only mutated in the 
 case of editing transients, then for the non-transient case ArrayNode is 
 effectively immutable but also safely published by any truly immutable data 
 structures by being referred to in final fields.

 Excellent! I had to look for myself, and now I feel much more comfortable 
 that Clojure is built upon the bedrock it needs to be :)

 On Tuesday, May 6, 2014 7:49:07 PM UTC-4, Alex Miller wrote:

 The Clojure persistent data structures are truly immutable - all fields 
 are final and referred objects are not mutated after construction so that 
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in 
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - 
 any of the Persistent*.java.

 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly 
 immutable (using final fields, relying on constructor freezing), or are 
 they mean to be merely effectively immutable (as defined in JICP)?



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Alex Miller
Hey Andy,

It does matter with regard to visibility across threads - your example does 
not use a synchronization mechanism and there is no guarantee that other 
threads will ever see those changes (so don't ever ever do that :). But if 
you stick to the normal Clojure apis, all is good. I'd highly recommend 
reading JCIP to dive into the details. 

Final field freeze is particularly weird and it baked my noodle when I 
first encountered it - here's a blog I wrote about it approx 697 years ago 
in internet time (and Brian Goetz backs me up in the comments :)
http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/

Alex


On Tuesday, May 6, 2014 7:35:43 PM UTC-5, Andy Fingerhut wrote:

 Alex, I may be unfamiliar with the definitions of truly immutable and 
 effectively immutable being used here, but if I can mutate the contents of 
 a Java Object array that is a final field after an object is constructed, 
 does it really matter that much if it is final?  It is trivially easy to 
 mutate using Java access.  Here is the example that I mentioned earlier in 
 this thread, copied here for convenience:

 user= (def v [1 2 3])
 #'user/v
 user= (class v)
 clojure.lang.PersistentVector
 user= v
 [1 2 3]
 user= (aset (.tail v) 1 -2)
 -2
 user= v
 [1 -2 3]

 Andy


 On Tue, May 6, 2014 at 4:49 PM, Alex Miller al...@puredanger.comjavascript:
  wrote:

 The Clojure persistent data structures are truly immutable - all fields 
 are final and referred objects are not mutated after construction so that 
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in 
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - 
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly 
 immutable (using final fields, relying on constructor freezing), or are 
 they mean to be merely effectively immutable (as defined in JICP)?

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.comjavascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-06 Thread Alex Miller
True! Hash codes are a special case - the pattern they use is sometimes 
called the racy single-check idiom and is discussed in Effective Java in 
Item 71 or on an internet near you. The canonical example of this is 
java.lang.String. The trick is that if you don't have a non-0 hash code, 
compute it yourself and stash it. If threads happen to see it, they can use 
it! If they don't see it, they compute it themselves. If two threads race, 
they write the *same* value, so everyone is fine. One important aspect is 
that the hash code must be an int which can be written atomically; if it 
was a long, you'd potentially be subject to long tearing.  

As of Clojure 1.6, Symbols also use this idiom for hasheq. Keywords do not 
- the assumption with keywords is that they are likely to be used as keys 
and so the hasheq is pre-computed and cached during construction (but 
keywords are re-used so this is only done once per keyword).


On Tuesday, May 6, 2014 7:07:37 PM UTC-5, tbc++ wrote:

 And hash codes are not final as they are calculated on-the-fly on most of 
 the Clojure data structures. 

 Timothy


 On Tue, May 6, 2014 at 5:49 PM, Alex Miller al...@puredanger.comjavascript:
  wrote:

 The Clojure persistent data structures are truly immutable - all fields 
 are final and referred objects are not mutated after construction so that 
 freeze occurs.  One obvious exception are the transient variants (
 http://clojure.org/transients). You can look at the code in 
 https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang - 
 any of the Persistent*.java.


 On Tuesday, May 6, 2014 4:11:49 PM UTC-5, Mike Fikes wrote:

 Are the persistent immutable data structures in Clojure truly 
 immutable (using final fields, relying on constructor freezing), or are 
 they mean to be merely effectively immutable (as defined in JICP)?

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.comjavascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




 -- 
 “One of the main causes of the fall of the Roman Empire was that–lacking 
 zero–they had no way to indicate successful termination of their C 
 programs.”
 (Robert Firth) 


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.