(conj collection item)
adds item
to collection
. To do that, it needs to realize collection
. (I'll explain why below.) So the recursive call happens immediately, rather than being deferred.
(cons item collection)
creates a sequence which begins with item
, followed by everything in collection
. Significantly, it doesn't need to realize collection
. So the recursive call will be deferred (because of using lazy-seq
) until somebody tries to get the tail of the resulting sequence.
The following is how it works internally:
cons
actually returns a clojure.lang.Cons
object, which is what lazy sequences are made of. conj
returns the same type of collection which you pass it (whether that is a list, vector, or whatever else). conj
does this using a polymorphic Java method call on the collection itself. (See line 524 of clojure/src/jvm/clojure/lang/RT.java
.)
What happens w