[start slightly insane idea]
Perhaps we need the following: * a way to tag a function as _pure_ * a map with uber_weak keys + values by "uber_weak", I mean the k/v pair vanishes when either the key _or_ the value is gc-ed Then, what we do here, is that every function auto-memoizes: (func args) ==> * lookup in my uber_weak k/v map; if args is already there, return last computed value * if not, compute value, then put it into the uber_weak k/v map Suppose "uber_weak" maps exist, this does not cause gc problems because: * if our uber_weak map is the last reference to the either the k or the v, the entire k/v pair gets removed from the uber_weak map [end slightly insane idea] I'm also going to mention that I know no where near enough about js/java GC to say anything about how to implement "uber_weak" maps. On Wed, Feb 26, 2014 at 8:37 PM, Bobby Eickhoff <beickh...@gmail.com> wrote: > This seems like a reasonable optimization. I read something similar a few > years ago > (http://lorgonblog.wordpress.com/2008/05/24/catamorphisms-part-four/): > > What we want is a function which will be smart, and only allocate new data > structures when necessary. Indeed, one of the main advantages of immutable > data structures is the ability to "share" portions of structure. > > > Bobby > > On Monday, February 24, 2014 4:00:34 PM UTC-5, Brian Craft wrote: >> >> 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. -- 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.