Can somebody rewrite this (plt) Scheme code into Clojure?
(define (f n)
(printf "(f ~a)~n" n)
(g n))
(define (g n)
(printf "(g ~a)~n" n)
(h n))
(define (h n)
(printf "(h ~a)~n" n)
(f (+ n 1)))
In such a way as to not collapse the procedures f, g, and h together and to allow the code to run indefinitely without crashing?
Since Clojure uses the Java calling conventions, it cannot, and does not, make the same tail call optimization guarantees. Instead, it provides the recur special operator, which does constant-space recursive looping by rebinding and jumping to the nearest enclosing loop or function frame.
Tail Recursion In Clojure Unlike compilers of some other functional languages, Clojure's compiler will not automatically detect a recursive tail-call and optimise it accordingly. We need to make the tail call using a special form, recur , to explicitly utilise tail recursion optimisation.
Use a trampoline:
(declare f)
(defn h [n]
(println "(h " n ")")
#(f (+ n 1)))
(defn g [n]
(println "(g " n ")")
#(h n))
(defn f [n]
(println "(f " n ")")
#(g n))
Kick it off with:
(trampoline f 0)
I've had this code running on my pc in the background for about 5 hours now and the memory usage is flat.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With