Search code examples
recursionvectorclojureliterals

(vec) vs [ ] vector literal


I've got two functions here that I though would return the same thing but they don't. I can't for the life of me figure out why. Any ideas?

user=> (defn foo [x] (when (> x 0) (conj (vec (foo (dec x))) x)))
#'user/foo
user=> (defn bar [x] (when (> x 0) (conj [(bar (dec x))] x)))
#'user/bar
user=> (foo 5)
[1 2 3 4 5]
user=> (bar 5)
[[[[[nil 1] 2] 3] 4] 5]

Solution

  • [xs] creates a one-element vector, containing the single item xs. In contrast, (vec xs) does not create a one-element vector containing the item xs. Instead, it creates an n-element vector, containing each item in xs separately. A function which does the former is vector: (vector x y z) is conceptually the same as [x y z]. Compare to (list x) and (seq x): the former creates a one-element sequence containing its input, while the latter converts its input to a sequence.

    Of course, if you are going to conj onto the result of vector you might as well just build the 2-element vector directly: instead of (conj (vector x) y), write [x y].