I am a newbie in Clojure.The problem originated when I once checked the source code of conj:
(def conj
(fn ^:static conj
([] [])
([coll] coll)
([coll x] (clojure.lang.RT/conj coll x));4
([coll x & xs] ;1
(if xs ;2
(recur (clojure.lang.RT/conj coll x) (first xs) (next xs)) ;3
(clojure.lang.RT/conj coll x)))))
The source code of conj shows that it uses recur to implement the function. This source code looks very simple.
What I'm confused about is the condition it uses when determining whether recursion needs to continue. It looks like it checks if the variable parameters is nil , but if the variable parameters is nil, it will soon be equivalent to the third "arity" of conj?
I then tried to evaluate the following expression:
user=> (conj [] 1 (next []))
[1 nil]
user=>
It works normally and successfully adds nil to the vector. I understand that clojure actually wraps nil in a list and passes it to the function, but I don't understand why recur can pass a real nil in ? And why does clojure recognize and match the correct "arity"?
user=> (def my_conj
(fn [coll x & xs]
(println "xs is" xs)
(if xs
(recur (clojure.lang.RT/conj coll x) (first xs) (next xs))
(clojure.lang.RT/conj coll x))))
#'user/my_conj
user=> (my_conj [] 1 (next []))
xs is (nil)
xs is nil
[1 nil]