Re: Code problem: setting an atom from a deref'd atom that's inside a let.
Tim Robinson tim.blacks...@gmail.com writes: = (defn oops! [] (let [x1 (atom (hash-map)) v1 (filter #(let [xv1 (@data %)] (if (= xv1 v1) (swap! x1 assoc :k1 other))) (keys @data)) rxv (reset! flag @x1)] (println v1))) So why didn't the first version with deref work? Because `filter' produces a lazy list, which isn't realized (and the side effects generated) until your call to `println'. Furthermore, the documentation for `filter' explicitly notes that pred must be free of side-effects. Looking at the implementation, I'm not sure why function-argument purity matters more for `filter' than any other sequence-generating higher-order function. Does anyone else know the reason? -Marshall -- 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
Re: Code problem: setting an atom from a deref'd atom that's inside a let.
On Tuesday, October 25, 2011 12:00:04 PM UTC-4, Tim Robinson wrote: This code probably will not make a whole lotta sense since I reduced it down to show only the problem at hand, but I'm hoping someone can explain why this doesn't work the way I expected it would: = (def data (atom {:k1 v1 :k2 v2 :k3 v3})) #'user/data = (def flag (atom nil)) #'user/flag = (defn oops! [] (let [x1 (atom (hash-map)) v1 (filter #(let [xv1 (@data %)] (if (= xv1 v1) (swap! x1 assoc :k1 other))) (keys @data)) rxv (reset! flag @x1)] (println v1))) = (oops!) (:k1) nil = @flag {} I had expected this flag would now hold the value from x1, but instead it's empty. No, it's not empty - it holds the value that x1 had at the time you swapped it, which is an empty map. Later, the x1 atom had its value changed, by then it was too late to affect flag. Specifically, x1 changed only when you printed v1, thus forcing realization of the lazy sequence that filter returned. Make sense? - Chris -- 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
Re: Code problem: setting an atom from a deref'd atom that's inside a let.
Yes, that does. Thanks to both of you. Tim On Oct 25, 10:16 am, Chris Perkins chrisperkin...@gmail.com wrote: On Tuesday, October 25, 2011 12:00:04 PM UTC-4, Tim Robinson wrote: This code probably will not make a whole lotta sense since I reduced it down to show only the problem at hand, but I'm hoping someone can explain why this doesn't work the way I expected it would: = (def data (atom {:k1 v1 :k2 v2 :k3 v3})) #'user/data = (def flag (atom nil)) #'user/flag = (defn oops! [] (let [x1 (atom (hash-map)) v1 (filter #(let [xv1 (@data %)] (if (= xv1 v1) (swap! x1 assoc :k1 other))) (keys @data)) rxv (reset! flag @x1)] (println v1))) = (oops!) (:k1) nil = @flag {} I had expected this flag would now hold the value from x1, but instead it's empty. No, it's not empty - it holds the value that x1 had at the time you swapped it, which is an empty map. Later, the x1 atom had its value changed, by then it was too late to affect flag. Specifically, x1 changed only when you printed v1, thus forcing realization of the lazy sequence that filter returned. Make sense? - Chris -- 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
Re: Code problem: setting an atom from a deref'd atom that's inside a let.
Good question. Also, I wonder if there are any existing realize type functions? i.e. (realize (filter ...)) or how would I realize without printing? Tim On Oct 25, 10:12 am, Marshall T. Vandegrift llas...@gmail.com wrote: Tim Robinson tim.blacks...@gmail.com writes: = (defn oops! [] (let [x1 (atom (hash-map)) v1 (filter #(let [xv1 (@data %)] (if (= xv1 v1) (swap! x1 assoc :k1 other))) (keys @data)) rxv (reset! flag @x1)] (println v1))) So why didn't the first version with deref work? Because `filter' produces a lazy list, which isn't realized (and the side effects generated) until your call to `println'. Furthermore, the documentation for `filter' explicitly notes that pred must be free of side-effects. Looking at the implementation, I'm not sure why function-argument purity matters more for `filter' than any other sequence-generating higher-order function. Does anyone else know the reason? -Marshall -- 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
Re: Code problem: setting an atom from a deref'd atom that's inside a let.
Never mind... I just used 'count'. And sorry to spam the group. On Oct 25, 10:44 am, Tim Robinson tim.blacks...@gmail.com wrote: Good question. Also, I wonder if there are any existing realize type functions? i.e. (realize (filter ...)) or how would I realize without printing? Tim On Oct 25, 10:12 am, Marshall T. Vandegrift llas...@gmail.com wrote: Tim Robinson tim.blacks...@gmail.com writes: = (defn oops! [] (let [x1 (atom (hash-map)) v1 (filter #(let [xv1 (@data %)] (if (= xv1 v1) (swap! x1 assoc :k1 other))) (keys @data)) rxv (reset! flag @x1)] (println v1))) So why didn't the first version with deref work? Because `filter' produces a lazy list, which isn't realized (and the side effects generated) until your call to `println'. Furthermore, the documentation for `filter' explicitly notes that pred must be free of side-effects. Looking at the implementation, I'm not sure why function-argument purity matters more for `filter' than any other sequence-generating higher-order function. Does anyone else know the reason? -Marshall -- 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
Re: Code problem: setting an atom from a deref'd atom that's inside a let.
Also, I wonder if there are any existing realize type functions? i.e. (realize (filter ...)) This is what doseq, dorun, and doall are for. jack. -- 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