Recursively change sequence in Clojure

I want to change the sequence in Clojure without using the reverse function and do it recursively.

Here is what I came up with:

 (defn reverse-recursively [coll] (loop [r (rest coll) acc (conj () (first coll))] (if (= (count r) 0) acc (recur (rest r) (conj acc (first r)))))) 

Output Example:

 user> (reverse-recursively '(1 2 3 4 5 6)) (6 5 4 3 2 1) user> (reverse-recursively [1 2 3 4 5 6]) (6 5 4 3 2 1) user> (reverse-recursively {:a 1 :b 2 :c 3}) ([:c 3] [:b 2] [:a 1]) 

Questions:

  • Is there a more concise way to do this, i.e. no loop / recur?
  • Is there a way to do this without using the β€œbattery” parameter in the loop?

Literature:

What is the best way to recursively convert a string in Java?

http://groups.google.com/group/clojure/browse_thread/thread/4e7a4bfb0d71a508?pli=1

+7
source share
7 answers
  • You do not need to count. Just stop when the remaining sequence is empty.
  • You do not have to prefill acc , as the original input may be empty (and this is more code).
  • Destruction is cool.
  (defn reverse-recursively [coll]
   (loop [[r & more: as all] (seq coll)
          acc '()]
     (if all
       (recur more (cons r acc))
       acc)))

As for loop / recur and acc , you need some way of going around a working inverted list. It either loop or adds another parameter to the function (this is really what loop does).

Or use a higher order function:

  user => (reduce conj '() [1 2 3 4])
 (4 3 2 1)
+22
source

Yes to question 1, this is what I came up with for my answer to koan recursion (I could not tell you whether it was a good clojure practice or not).

 (defn recursive-reverse [coll] (if (empty? coll) [] (conj (recursive-reverse (rest coll)) (first coll) ))) 
+3
source

To exhaust more than one method, into used. Since in internal use conj it can be used as follows:

 (defn reverse-list "Reverse the element of alist." [lst] (into '() lst)) 
+2
source

The current version of Clojure has a built-in function called rseq . For those who pass by.

+1
source
 (defn my-rev [col] (loop [ col col result []] (if (empty? col) result (recur (rest col) (cons (first col) result))))) 

Q1.

The JVM cannot optimize recursion, a recursive function that will directly overflow the stack. Therefore, in Clojure, which uses the / recur loop. Thus, without using a function that repeats, deep recursion cannot be defined. (which is also used internally for reuse as a trampoline function.)

Q2.

recursive function with recur, must be tail recursive. If the normal recursive function changes to the tail-recursion function, therefore, as an accumulator, the need to transfer the value of the variable is required.

0
source
 (defn reverse-seq [sss] (if (not (empty? sss)) (conj (reverse-seq (rest sss)) (first sss)) ) ) 
0
source
 (defn recursive-reverse [coll] (if (empty? coll) () (concat (vector (peek coll)) (recursive-reverse (pop coll ))) ) ) and test: user=> (recursive-reverse [1]) (1) user=> (recursive-reverse [1 2 3 4 5]) (5 4 3 2 1) 
0
source

All Articles