So I’m rewriting this post because I got off on a tangent before, so here’s the deal.
Clearly state the problem: I work in Actionscript a ton. I love recursion. Flash will only let you recurse 256 levels before crashing. We need a way to run code recursively as deep as we need to without crashing the player and without filling up the call stack. In short we need tail-call optimization.
Tail-call optimization is quite a simple concept.
Look at this code it’s just a really stupid way to add two numbers
function StupidAdder(a,b)
{
if(b==0) return a;
return StupidAdder(a+1,b-1);
}
trace(StupidAdder(10,20));
This works fine, unless the second number is over 256 (oh and don’t make the second number negative it won’t work either).
The big problem here is that even though we are calling return Adder(a+1,b-1); Flash still keeps the stack frame for the whole function around even though it’s no longer necessary. The only thing we need to remember is that when we get to the end that we need to return the final value to the trace statement. So anyway I wrote this code that adds two methods to each function you create.
_global.Function.__proto__.TailCall=function()
{
arguments.unshift(this);
throw(arguments);
}
_global.Function.__proto__.WithTailCall=function()
{
arguments.unshift(this);
var c=arguments;
var rtn=null;
while(c)
{
try
{
rtn=c.shift().apply(null,c);
c=null;
}
catch(v)
{
c=v;
}
}
return rtn;
}
This uses a try catch block to pop the stack and then call the next function needed. When a normal value is returned it just gets passed directly to the original requester. Now we can call our StupidAdder function like such.
function StupidAdder(a,b)
{
if(b==0) return a;
StupidAdder.TailCall(a+1,b-1);
}
trace(StupidAdder.WithTailCall(10,256));
And there you have it, completely unnecessary in this case, but a nice little gem to have in your back pocket for that one time you want to run a function that recurses 1000 times.