Hi Charles,
I found some interesting implementations of the Ackermann function. Creating the function with 3 recursive calls seems to be very exhaustive to the stack, direct computing for m<4 seems to save resources and calculates higher values:
ackermann2.o2bas:
' http://largeint.sourceforge.net/Ackerman.htm
uses console
int c,s,d
sub init_counts()
   c=0 : s=0 : d=1
end sub
' Naive implementation with three recursive calls:
function A (int m, n) as int
   c = c + 1
   s = s + 1
   if s > d then d = s
   if m = 0 then
      function = n + 1
   elseif n = 0 then
      function = A(m - 1, 1)
   else
      function = A(m - 1, A(m, n - 1))
   end if
   s = s - 1
end function
init_counts() : printl "Ackermann function A(m,n) - three recursive calls"
init_counts() : printl "A(3, 7) = " : print A(3,7)  tab " calls: " c " depth: " d '1021
init_counts() : printl "A(3,12) = " : print A(3,12) tab " calls: " c " depth: " d '32765; A(3,13) -> stack overflow
init_counts() : printl "A(4, 0) = " : print A(4,0)  tab " calls: " c " depth: " d '13; A(4,1) -> stack overflow
' Cheat - direct computation for m < 4
function A (int m, n) as quad
   c++
   s++
   if s > d then d = s
      select case m
      case 0
         function = n + 1
      case 1
         function = n + 2
      case 2
         function = 2 * n + 3
      case 3
         function = 2 ^ (n + 3) - 3
      case else
         if n = 0 then
            function = A(m - 1, 1)
         else
            function = A(m - 1, A(m, n - 1))
         end if
      end select
   s--
end function
printl
init_counts() : printl "Ackermann function A(m,n) - direct computation for m < 4 "
init_counts() : printl "A(3, 7) = " : print A(3,7)  tab " calls: " c " depth: " d '1021
init_counts() : printl "A(3,12) = " : print A(3,12) tab " calls: " c " depth: " d '32765; A(3,13) -> stack overflow
init_counts() : printl "A(4, 0) = " : print A(4,0)  tab " calls: " c " depth: " d '13; A(4,1) -> stack overflow
printl
init_counts() : printl "A(3,20) = " : print A(3,20) tab " calls: " c " depth: " d '8388605
init_counts() : printl "A(3,30) = " : print A(3,30) tab " calls: " c " depth: " d '858934589
init_counts() : printl "A(4, 1) = " : print A(4, 1) tab tab " calls: " c " depth: " d '65533; A(4,2) too much -> 19729 digits
init_counts() : printl "A(5, 0) = " : print A(4, 1) tab tab " calls: " c " depth: " d '65533; A(5,1) wrong result
printl "Enter ..."
waitkey
How would you code the second approach in Leanlisp? I noticed that you already have done the first approach in examples/math/Ackermann.o2bas, but somehow print (ack 3 7) does not work for me. What did I do wrong?
Roland
ackerLean.o2bas:
% UseSystemConsole
uses Console
uses LispishUtil
string src=quote """
( let ack " m n
  (if (> m 0 )
    (if (> n 0)
      (eval
        (decr m)
        (decr n)
        (let t (ack n 1))
        (ack m t)
      )
      ;else n=0
      (eval
        (decr m)
        (ack m 1)
      )
    )
    ;else m=0
    (+ n 1)
  ) ;end if m>0
")
print (ack 3 7)
"""
string s=lisp src
printl "Enter"
waitkey