The most important thing you need to know about is that the sequences in Clojure are lazy. This means that elements in a sequence are evaluated only when they are needed. This allows you to work with infinite sequences.
In most cases, this is what you want, but it can be confusing when you are really not interested in the values โโof the elements of the sequence, but in the side effects of the functions that create the elements of the sequence. In your example, the sequence consists of 100 return values โโof the println function, i.e. 100 times nil - not very interesting. But the println function has the side effect of printing "Hello World" on standard output.
The problem is that if you never do anything with elements in a sequence, println functions are never evaluated and lines are not printed. It works in REPL, because P in REPL means print - it returns the return value of the expression you entered. To print the entire sequence, it must be evaluated, so you see a bunch of "Hello World", but also a bunch of nils . If you run the code outside of REPL (without using the return value), you will not see Hello Worlds.
If you are interested in the side effects of your element generating functions, you can use doall or doseq . doall forcibly evaluates the entire sequence and returns it:
(doall (for [a (range 100)] (println "Hello World")))
doseq does not return a sequence (it returns nil ) and has syntax like for :
(doseq [a (range 100)] (println "Hello World"))
Also note that you really only need to specify the desired counter (100) only once. The range function already produces a sequence with 100 elements in it. Suggestion :while in your code is redundant, as is the take function (there are not many choices of the first 100 elements from a sequence of 100 elements).
Hope this helps!
source share