Clojure Community Blog from August, 2011

Hi All,

I am a Clojure newbie and can't figure out why the following code (1.2.1 or 1.3.0 beta1):

(for [i (range 1 3)] (println \b))
(b
b
nil nil)
user=> (for [i (range 1 3)] (println \b))

Prints this in REPL:

user=> (b

b

nil nil)

Since println is supposed to return nil, I expected (nil, nil) to be returned. In reality, the value(\b) that was supposed to be only printed, is also (apparently) returned in the result collection

Ok, let's take this apart some more:

user=> (def f (for [i (range 1 3)] (println \b)))

user=> f

(b

b

nil nil)

Still surprising - I thought I was defining a variable with value being the result of the for macro execution, but it either executed again when f was evaluated, or the result actually contains printed (not captured) values...

Final experiment:

user=> ((vec f) 0)

nil

user=> ((vec f) 1)

nil

user=> ((vec f) 2)

IndexOutOfBoundsException

Now, this reveals that the result actually was correct all along. It is unclear why REPL decided to make the printed values part of the result. Maybe it started with an open parenthesis too early? E.g. it should have printed

b

b

(nil nil)

If so, this is a minor (but confusing for the unitiated) bug. What was more surprising to me is that evaluating f apparently re-evaluated the for. Is this really so? This is not true in the following case:

user=> (defn f3[] (do (println "call") 1))
user=> (def f (f3))
call
#'user/f
user=> f
1
Here f3 is evaluated once, and not re-evaluated when f is computed. What's the difference from the previous example with for? Am I missing something essential here?

Thanks in advance,
Julian