2 ms·
My brain automatically refactors what you wrote into the following: (define countdown (letrec ((cd (lambda (n) (if (> n 0)
by waterhouse 12y ago
My brain automatically refactors what you wrote into the following:
(define countdown
(letrec ((cd
(lambda (n)
(if (> n 0)
(cons n (cd (- n 1)))
'(liftoff)))))
cd))
Which should be equivalent. As for what Clojure provides, the Clojure docs say this: "No letrec, labels or flet - use (fn name [args]...) for self-reference, letfn for mutual reference. Thus, this would be the Clojure version:
(def countdown
(fn cd [n]
(if (pos? n)
(cons n (cd (- n 1)))
'(LiftOff))))
In fact, it also works to use the name "countdown" in the fn form. You could define your own version of "defn" that used fn like this, to make internally self-recursive functions (as opposed to ones that go through the current global binding of the function's name) by default. I am not actually sure that this is a bad default behavior. (The main problem that comes to mind is if someone replaces it with a "traced" version, that debug-prints its arguments in addition to what it normally does, and expects to see debug-printing of the recursive calls.)