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

Reply via email to