// fibonacci.cm — Fibonacci variants kernel // Tests recursion overhead, memoization patterns, iteration vs recursion. // Naive recursive (exponential) — measures call overhead function fib_naive(n) { if (n <= 1) return n return fib_naive(n - 1) + fib_naive(n - 2) } // Iterative (linear) function fib_iter(n) { var a = 0 var b = 1 var i = 0 var tmp = 0 for (i = 0; i < n; i++) { tmp = a + b a = b b = tmp } return a } // Memoized recursive (tests object property lookup + recursion) function make_memo_fib() { var cache = {} var fib = function(n) { var key = text(n) if (cache[key]) return cache[key] var result = null if (n <= 1) { result = n } else { result = fib(n - 1) + fib(n - 2) } cache[key] = result return result } return fib } // CPS (continuation passing style) — tests closure creation function fib_cps(n, cont) { if (n <= 1) return cont(n) return fib_cps(n - 1, function(a) { return fib_cps(n - 2, function(b) { return cont(a + b) }) }) } // Matrix exponentiation style (accumulator) function fib_matrix(n) { var a = 1 var b = 0 var c = 0 var d = 1 var ta = 0 var tb = 0 var m = n while (m > 0) { if (m % 2 == 1) { ta = a * d + b * c // wrong but stresses numeric ops tb = b * d + a * c a = ta b = tb } ta = c * c + d * d tb = d * (2 * c + d) c = ta d = tb m = floor(m / 2) } return b } return { fib_naive_25: function(n) { var i = 0 var x = 0 for (i = 0; i < n; i++) x += fib_naive(25) return x }, fib_naive_30: function(n) { var i = 0 var x = 0 for (i = 0; i < n; i++) x += fib_naive(30) return x }, fib_iter_80: function(n) { var i = 0 var x = 0 for (i = 0; i < n; i++) x += fib_iter(80) return x }, fib_memo_100: function(n) { var i = 0 var x = 0 var fib = null for (i = 0; i < n; i++) { fib = make_memo_fib() x += fib(100) } return x }, fib_cps_20: function(n) { var i = 0 var x = 0 var identity = function(v) { return v } for (i = 0; i < n; i++) { x += fib_cps(20, identity) } return x }, fib_matrix_80: function(n) { var i = 0 var x = 0 for (i = 0; i < n; i++) x += fib_matrix(80) return x } }