1

So I tried to write a tail-recursive exponentiation (for positive integer exponents). I came with this (it's exponentiation by squaring):

(define (^ n k)
  (define (helper n k acc)
    (cond
      [(zero? k) acc]
      [(even? k) (helper (* n n) (/ k 2) acc)]
      [else (helper n (- k 1) (* n acc))]))
  (helper n k 1))

If however I try to run it with big argument, I always get to Racket virtual machine has run out of memory; aborting. Why this function is not considered tail-recursive? Every condition leads straight to either recursive execution, or terminal symbol.

enedil
  • 1,605
  • 4
  • 18
  • 34
  • 3
    Your function *is* tail recursive. Is it possible that the number you are calculating is legitimately just enormous enough to run out of memory computing it? Even if you aren’t allocating stack frames, Racket’s numbers are arbitrary-precision, and they aren’t free. What is “a big argument” in this case? – Alexis King Jul 02 '17 at 12:22
  • @AlexisKing I tried `(^ 2 (^ 2 1000))` just to see the difference, but you may be right. – enedil Jul 02 '17 at 12:35
  • 1
    Yes, that number is very, very large! I am not surprised you exhaust the memory limit computing it. Note that using the built-in `expt` instead of your `^` fails in the same way, despite likely being even more efficiently implemented. – Alexis King Jul 02 '17 at 12:38
  • 2
    That number has a bit over 17.4 * 10^300` digits. – soegaard Jul 02 '17 at 14:09
  • 1
    ... so you'd need to store 10^220 digits in each particle in the visible universe. – molbdnilo Jul 03 '17 at 17:34

0 Answers0