Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What causes this for loop to print a series of nil?

Tags:

clojure

Can anyone explain what causes all the nil values in the following?

(defn my-for []
   (for [n (range 0 40)]
     (println n)))
(my-for)

Result (omitting some numerical values):

(0 1 2 ... 30 31 nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 32 33 ... 38 39 nil nil nil nil nil nil nil nil nil)

like image 223
droidballoon Avatar asked Jun 28 '13 20:06

droidballoon


2 Answers

this is a mix of the output of the print statement and printing the result of the for expression.

the for produces a sequence of the return value of println, which is always nil

user> (defn my-for []                                                                                                                                                     
           (for [n (range 0 40)]                                                                                                                                          
                     (println n)))                                                                                                                                        
#'user/my-for                                                                                                                                                             
user> (def ansewr (doall (my-for)))                                                                                                                                       
0                                                                                                                                                                         
1                                                                                                                                                                         
2                                                                                                                                                                         
3                                                                                                                                                                         
...                                                                                                                                                                       
38                                                                                                                                                                        
39                                                                                                                                                                        
#'user/ansewr                                                                                                                                                             
user> ansewr                                                                                                                                                              
(nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)  

These two are being printed ontop of each other by the repl

like image 107
Arthur Ulfeldt Avatar answered Oct 02 '22 13:10

Arthur Ulfeldt


for is a list comprehension operator, its return value is a list. The return value of println is always nil, and those are the values that for is using to build the list it returns. Since you are (println n), your prints interleave with the REPL's printing of the return value for the for.

If you avoid the use of println in the for, the REPL will show you the list of numbers from 0 to 39:

(defn my-for []
   (for [n (range 0 40)] n))
(my-for)
;= (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39)

If you only want to print the values then you can use the doseq form, which is used for side-effecting functions (such as println) and always returns nil:

(defn my-doseq []
   (doseq [n (range 0 40)] 
     (println n)))
(my-doseq)
like image 34
juan.facorro Avatar answered Oct 02 '22 14:10

juan.facorro