So, looks like I've got Tail Call Optimized Recursion working in my #Lisp implementation. The trick is to make sure that you're letting the invocation of the child function happen without any other work to be done.

My first implementation evaluated subexpressions and multiplied. This version passes an accumulator down, and the interpreter is smart enough to turn that into an iterative (ish?) pass through the EVAL loop, rather than an extra frame on the stack. Take that, 1000 factorial!

I sent that 1000! picture to a friend on #Hangouts (which #Google hasn't shut down... yet), and my friend commented on the large number of 0s at the end of the value.

I assured him that that's what happens with #factorials - by 5! you've got 2*5 as a subexpression, and by 10! you've got another factor of 10, well, right there. 15 brings in another factor of 5, and by that point, you've got a backlog of 2s. 25! has six trailing zeroes, with two factors of 5 right there.

That's #math for you.