;; 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.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 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 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.