As Andy indicated, it is almost never a good idea to wrap something
mutable in a reference type simply because the guarantees of references
do not hold for mutable things. In other words, the thing the ref points
to can be changed without going through the ref which defeats the whole
purpose of refs! If you absolutely need an native array, then forget
about refs, otherwise clojure vectors might be a better fit...
Jim
ps: just a side note...STM refs should really be the last ref type to
consider...I mean you can get away with just using
atoms/futures/promises/agents in a lot of cases...
On 21/09/12 03:05, Andy Fingerhut wrote:
Piotr:
The most direct answer to your specific question is that aset-int modifies the
array, and returns the value 9. The return value 9 is what the ref r is being
set to after the (dosync (alter ...)) call.
However, there is a bigger issue here. Even if you replace aset-int with a
different function that modifies the Java array and then returns the modified
array, it won't be possible to use Clojure dosync transactions correctly like
that.
I think that refs should only "point at" immutable data structures, never mutable ones like Java
arrays, and functions given to alter should be pure functions with no side effects. Why? Because dosync
transactions can be partially done, conflict with another transaction, and be restarted. If they are
modifying mutable Java arrays part way through, dosync has no way to "undo" those mutations. The
whole reason that Clojure's STM is able to be implemented as it is, is because *only* the refs, agents, and
atoms can change, but all of the things they "point to" are immutable.
Feel free to ask a followup question if that didn't make sense :-)
Andy
On Sep 20, 2012, at 1:40 PM, Piotr Gorak wrote:
I create a ref to an array:
(def r (ref (make-array Integer/TYPE 5)))
(type @r) -> [I
Then, I try to alter the array:
(dosync
(alter r aset-int 0 9))
I would then expect to be able to write (aget @r 0) and get result of 9, but
what actuall happens is that r becomes reference to java.lang.Long!
(type @r) -> java.lang.Long
What is wrong?
Piotr
--
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