View Full Version : Best / Most elegant way to unwind a recursive function?
maskedMan
10-27-2010, 08:27 PM
One of my favorite golden hammers is the recursive function.
private function recurse(obj:*):*{
var shouldRecurse:Boolean = true;
// do stuff...
// stuff might change value of shouldRecurse to false
if(shouldRecurse){
return recurse(obj);
}
return obj;
}
The possible danger with such a function (in the Flash Player, at least) is that if it recurses too many times you'll get a stack overflow in the middle of your chain, as the memory available to the stack is depleted. That's no fun at all!
So, I've only encountered this one time. I came up with a solution that I felt was inelegant, but it worked. I'm curious whether there is an elegant way to let a recursive function's call stack "breathe" and then jump right back into processing if the chain is NOT yet complete.... or whether such a request is reasonable, or if the situation might be an indication that a different solution is called-for.
senocular
10-27-2010, 08:31 PM
If I hit a limit like that (or fear I will) I'll usually convert the function from being recursive to instead being handled within a loop.
Personally I use this only for limited scope recursion like looking through an xml (shouldn't get thousands of recursion) or such. When I know that the recursion can regularly happen hundreds or more times I use a different system.
I recently had to create a system where my code would regularly get to the stack overflow limit. Basically user can draw a room (any size, any complexity), then add objects to fill the room (window, door, furniture) and then click calculate so the application would calculate the amount and placement of tiles in the empty areas. The bigger the room the more loops and the closest the stack overflow I would get. So I calculate the number of loop I need, set a timer and run 2000 loops on each tick. The cool thing is that I'm able to display a progress bar. With the biggest room the process takes up to 1 minute but really the progress bar makes people not care at all!
TomMalufe
10-28-2010, 01:04 PM
Nice solution ASWC! I like the sound of that a lot!
newblack
10-28-2010, 03:13 PM
I wrote a library a while ago that handles this problem: http://blog.generalrelativity.org/actionscript-30/green-threads/
It offers a structured way to decompose recursion/large loops. In practice it can really increase a problem's complexity, so it should be used with caution. I think it's best for places where you're doing a noticeably large amount of processing; where the UI becomes unresponsive.
Not sure if its in the same vain as whats being discussed here, but this article is a good read. (Actually it was maskedMan whom mentioned the article here at the forum in another thread awhile ago.)
Asynchronous ActionScript Execution (by senocular)
http://www.senocular.com/flash/tutorials/asyncoperations/?page=1
Thought it may be worth a mention here.
maskedMan
10-28-2010, 06:07 PM
NewBlack: That looks almost exactly like the Java implementation of a thread, redone using Flash Timer objects. I'd done something very similar on a previous project, but not to that degree of replication. Pretty neat to see someone else come up with the idea.
I actually checked newblack framework when I was looking for a solution (he posted that link a while back) and I would have used it except there wasn't a way to track progress which I really wanted (to create a progress bar) so I ended with my own timer system. Maybe I missed it and there's a way to track progress? If not you should really add that.;)
Not sure if its in the same vain as whats being discussed here, but this article is a good read. (Actually it was maskedMan whom mentioned the article here at the forum in another thread awhile ago.)
Asynchronous ActionScript Execution (by senocular)
http://www.senocular.com/flash/tutorials/asyncoperations/?page=1
Thought it may be worth a mention here.That's the kind of solution I used too so yes it's right on thread subject.
bowljoman
10-28-2010, 10:18 PM
I hate stack overflow!
I had to fix a project in which every function returned another function .
function doSomething(){
***
return otherDoSomething();
}
function otherDoSomething(){
***
return implDoSomething();
}
A few here and there is effective, but this SOB had 10 and 20 functions stacked up for no good reason. WHats worse, the SOB also had these stacked up on callReturn from a java server.
There was absolutely no way to tell where the errors occurred due to stack overflow. I spent a week unwinding the crud so that 50 million class methods were not called on every time the user sent something to the server. Idiot. When it got so bad that he could no longer debug, he wrapped the entire app in 'try/catch' with a print stack trace.... F'n trace was two pages long and crashed the browser half the time over a stupid null reference! YAAAAARRRRGHHH.... good money though, and awesome company to work for.
|
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.