Fibonacci tail recursion in JavaScript and Clojure. Conversion from iteration to recursion is done in the same ways as the basic conversion. Some steps are skipped to make the conversion concise.
// Recursion, but not tail call. Simple and easy to understand, but very slow.
// Note that negative numbers are not handled correctly to make it simpler throughout this post.
function fib(n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
function fib(n) {
let curr = 0;
let next = 1;
let i = 1;
while (i <= n) {
let prev = curr;
curr = next;
next = prev + curr;
i++;
}
return curr;
}
// - move loop condition to inside of while
// - return termination case early
// - use destructuring to assign variables
// - make index descreasing
function fib(n) {
let [i, curr, next] = [n, 0, 1];
while (true) {
if (i <= 0) return curr;
[i, curr, next] = [i - 1, next, curr + next];
}
}
function fib(n) {
let [i, curr, next] = [n, 0, 1];
loop: while (true) {
if (i <= 0) return curr;
[i, curr, next] = [i - 1, next, curr + next];
continue loop;
}
}
function fib(n) {
const loop = (i, curr, next) => {
if (i <= 0) return curr;
return loop(i - 1, next, curr + next);
}
return loop(n, 0, 1);
}
function fib(n, curr = 0, next = 1) {
if (n <= 0) return curr;
return fib(n - 1, next, curr + next);
}
const fib = (n, curr = 0, next = 1) => n <= 0 ? curr : fib(n - 1, next, curr + next);
;;; Note that the condition is flipped from the JS version above.
(defn fib
([n] (fib n 0 1))
([n curr next] (if (pos? n) (recur (dec n) next (+ curr next)) curr)))
(defn fib [n]
(loop [i n, curr 0, next 1]
(if (pos? i) (recur (dec i) next (+ curr next)) curr)))
Published: 2024-06-17
Tagged: clojure fp programming javascript