;; 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 <[email protected]> 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 <[email protected]> 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 <[email protected]>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 [email protected]
>>>>>
>>>>> Note that posts from new members are moderated - please be patient
>>>>> with your first post.
>>>>> To unsubscribe from this group, send email to
>>>>> [email protected]
>>>>>
>>>>> 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 [email protected].
>>>>>
>>>>> 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 [email protected]
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> [email protected]
>>> 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 [email protected].
>>> 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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.