On Sun, Jul 11, 2010 at 9:24 PM, Jeffrey Schwab <j...@schwabcenter.com> wrote:
> On 7/11/10 9:08 PM, Michał Marczyk wrote:
>>
>> On 12 July 2010 02:37, Jeffrey Schwab<j...@schwabcenter.com>  wrote:
>>>
>>> I did not know whether the sequence expressions (the right halves of the
>>> binding-forms) were evaluated strictly, or re-evaluated on each pass
>>> (like
>>> the body-expr).  They are apparently evaluated a priori, when the
>>> comprehension is defined:
>>
>> Actually the example I posted previously demonstrates that this is not
>> the case. Here's another one:
>>
>> user=>  (def a (atom #{1 2}))
>> #'user/a
>> user=>  (def f (for [i (range 2) j @a] [i j]))
>> #'user/f
>> user=>  (swap! a disj 1 2)
>> #{}
>> user=>  f
>> ()
>>
>> ...whereas without the intervening swap!...
>>
>> user=>  f
>> ([0 1] [0 2] [1 1] [1 2])
>>
>> Only the outermost expression is evaluated up front.
>
> Wow, that's non-intuitive.  Thanks!

Well, the behavior you're seeing there is because 'for' is lazy,
and none of the seq expressions is evaluated until the REPL is
asked to print 'f'.

Perhaps this would clear things up some:

        (defn r [i]
          (println (format "<range %d>" i))
          (range i))

        (for [a (r 2), b (r 3)] [a b])
        ; produces:
        <range 2>
        (<range 3>
        [0 0] [0 1] <range 3>
        [0 2] [1 0] [1 1] [1 2])

So just before seq is needed, the expression that produces that
seq is re-evaluated.  This is necessary because inner seq
expressions to the right can refer to locals defined further to
the left, thus their result could be different for each
iteration:

        (for [a (range 4), b (range (inc a))] [a b])
        ; produces, after formatting for clarity:
        ([0 0]
         [1 0] [1 1]
         [2 0] [2 1] [2 2]
         [3 0] [3 1] [3 2] [3 3])

Hope that helps,
--Chouser
http://joyofclojure.com/

-- 
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

Reply via email to