问题
((fn foo [x] (when (> x 0) (conj (foo (dec x)) x))) 5)
For this code, the result is [5 4 3 2 1] Why isn't is [1,2,3,4,5]? I see we do conf from result of recursive foo call with a value. For I thought it should be 1 2 3 4 5? Need help to understand this. Thanks.
回答1:
From the documentation of conj
:
clojure.core/conj
([coll x] [coll x & xs])
conj[oin]. Returns a new collection with the xs
'added'. (conj nil item) returns (item). The 'addition' may
happen at different 'places' depending on the concrete type.
The termination condition of your function yields nil
, because the test is a when. So the deepest conj call will be:
(conj nil 1)
(1) <-- a list
The next one:
(conj (conj nil 1) 2)
(2 1)
So your result will be in decreasing order because conj appends at the front for lists. If you want it in increasing order, start with an empty vector like this:
((fn foo [x] (if (> x 0) (conj (foo (dec x)) x) [])) 5)
[1 2 3 4 5]
回答2:
The recursive call expands to
(conj (conj (conj (conj (conj nil 1) 2) 3) 4) 5)
;(5 4 3 2 1)
The implicit nil
returned by (foo 0)
puns to ()
.
来源:https://stackoverflow.com/questions/31790557/clojure-recursion-conj-a-list