does that hold for languages/compilers with tail call optimisation?
The compiler would either have to memoize, or be extremely clever and start at the base case (0, 1) and then transform the code to use the 2x2 matrix exponentiation. I wouldn't have been suprised if GHC haskell was that clever, but even with -O2 "print $ fibb 10000" isn't terminating.
(define/contract (fib n)
(-> nonnegative-integer? nonnegative-integer?)
(let fib-recur ([i 1] [curr 1] [prev 0])
(cond [(= i n) curr]
[else (fib-recur (+ i 1)
(+ curr prev)
curr)])))fibb 0 = 0
fibb 1 = 1
fibb n = + (fibb (- n 1)) (fibb (- n 2))
into that, or any O(n) version.