Re: Code problem: setting an atom from a deref'd atom that's inside a let.

2011-10-25 Thread Marshall T. Vandegrift
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.

2011-10-25 Thread Chris Perkins
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.

2011-10-25 Thread Tim Robinson


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.

2011-10-25 Thread Tim Robinson
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.

2011-10-25 Thread Tim Robinson
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.

2011-10-25 Thread Jack Moffitt
 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