This is vaguely related to David's posts about om/react, where he talks 
about optimizing state change tracking by checking object identity on 
immutable objects: deep compares can be avoided if same identity implies no 
changes.

My first thought was that there are many algorithms that will give you a 
new object every time, even if nothing has changed.  E.g. if your state has 
an array whose elements must be validated, doing a map over the elements 
will give you a new array every time, even if it makes no changes.

Enforcing non-negative values, for instance:

=> (let [x {:a [1 -2 3]}] (update-in x [:a] (fn [y] (mapv #(if (< % 0) 0 %) 
y))))
{:a [1 0 3]}

In the following case the values are already non-negative, but we still get 
a new object:

=> (let [x {:a [1 2 3]}] (identical? x (update-in x [:a] (fn [y] (mapv #(if 
(< % 0) 0 %) y)))))
false

One can imagine trying to rewrite this so it passes through the vector if 
nothing has changed. E.g.

=> (let [x {:a [1 2 3]}] (identical? x (update-in x [:a] (fn [y] (reduce 
(fn [v i] (if (< (v i) 0) (assoc v i 0) v)) y (range (count y)))))))
true

=> (let [x {:a [1 -1 3]}] (identical? x (update-in x [:a] (fn [y] (reduce 
(fn [v i] (if (< (v i) 0) (assoc v i 0) v)) y (range (count y)))))))
false

I expect many algorithms would need to be reworked like this in order to 
rely on object identity for change tracking. Is this madness? Am I thinking 
about this the wrong way?


An interesting note here is that the next-to-last update-in, above, 
returned the same object. I didn't know update-in could return the same 
object. A simpler example:

=> (let [x {"a" [1 2 3]} y (update-in x ["a"] (fn [z] z))] [x y (identical? 
x y)])
[{"a" [1 2 3]} {"a" [1 2 3]} true]

=> (let [x {"a" [1 2 3]} y (update-in x ["a"] (fn [z] [1 2 3]))] [x y 
(identical? x y)])
[{"a" [1 2 3]} {"a" [1 2 3]} false]


Is this some kind of optimization in update-in, that it doesn't create a 
new object if the new attribute is identical to the old attribute? Is it 
peculiar to the data type? Is it documented anywhere?


-- 
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/groups/opt_out.

Reply via email to