Page 1 of 2
					
				recursion limit
				Posted: Wed Jun 06, 2012 11:09 am
				by Joerg
				Hi!
I am developing a discrete event simulation. Therefore is necessary to recursively call some handler as long as the future event list is not empty. However it is not possible to do this seriously because I permanently get the following error message although I do not reach 400000 recursions:
The handler: doRecursion has reached the recursion limit of: 400000. Execution will be terminated to prevent hang
In order to reproduce the problem, I have written the following code in a button script of a new Stack:
Code: Select all
local sRecursionLoop
on mouseUp
   put 1000 into sRecursionLoop 
   doRecursion
   answer "fertig"
end mouseUp
on doRecursion
   subtract 1 from sRecursionLoop
   if sRecursionLoop > 0 then doRecursion
end doRecursion
Can anyone help me please!
 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 11:20 am
				by Dixie
				Would 'send in time' help with what you are trying to do ?
Dixie
			 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 11:37 am
				by Joerg
				Hi Dixie,
unfortunately not because on one hand the simulation should run as fast as possible and shouldn't be delayed and on the other hand the error is still there if you use 'send in time'.
Joerg
			 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 11:51 am
				by Dixie
				Hi...
Code: Select all
local sRecursionLoop
on mouseUp
   put 1000 into sRecursionLoop
   doRecursion
   answer "fertig"
end mouseUp
on doRecursion
   repeat while sRecursionLoop > 0
      subtract 1 from sRecursionLoop
      put sRecursionLoop
     -- wait 0 millisecs with messages
   end repeat
end doRecursion
 This seems to work... if you employ the 'wait 0 millisecs' line you can see it counting down in the message box
be well
Dixie
 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 12:00 pm
				by Joerg
				Hi Dixie,
yes, you are absolutely right. Your code works but you have eliminated the recursion - but I need recursion (call the same handler from within the handler), e.g. for a sort algorithm or to generate a distribution of random numbers. That is what I have demontrated with:
Code: Select all
if sRecursionLoop > 0 then doRecursion
Any other idea?
 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 12:15 pm
				by Joerg
				By the way you also get the message error when you call one handler from another in recursion.
Example:
Code: Select all
local sRecursionLoop
on mouseUp
   put 1000 into sRecursionLoop
   executeSimulation
end mouseUp
on executeSimulation
   if sRecursionLoop > 0 then
      handleEventlist
   else
      answer "finished"
   end if
end executeSimulation
on handleEventlist
   subtract 1 from sRecursionLoop
   executeSimulation
end handleEventlist
 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 4:05 pm
				by Klaus
				Hi Joerg,
"recursionlimit" is NOT the number of runs of a handler but the size in bytes of the calls!
You can SET this to a higher value and see if that helps.
Check the dictionary for more info.
Best
Klaus
			 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 4:45 pm
				by Joerg
				Hi Klaus,
thx for your hint.
To give it a try I set the recursionLimit to 1000000 and increased the recursion to 10000 (please look at the code below). Then I got the error message again, just with the message that the handler has reached the recursion limit of: 983040
More over, it has no more impact to set the recursionLimit higher. However my discrete event simulation (and also my sample code here) needs a higher recursion limit!
So, isn't it possible to code an application with livecode where it is necessary to loop through tasks as long as a "task list" is not empty? That would be serious weakness for scientific applications.
Do you have another idea?
Here is the modified sample code:
Code: Select all
local sRecursionLoop
on mouseUp
   put 10000 into sRecursionLoop
   executeSimulation
end mouseUp
on executeSimulation
   if sRecursionLoop > 0 then
      set the recursionLimit to 1000000
      handleEventlist
   else
      answer "finished"
   end if
end executeSimulation
on handleEventlist
   subtract 1 from sRecursionLoop
   executeSimulation
end handleEventlist
 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 5:20 pm
				by Klaus
				Hi Joerg,
sorry, no idea.
Best
Klaus
			 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 5:40 pm
				by Joerg
				Hi Klaus,
thank you
Best
Jörg
			 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 5:50 pm
				by mwieder
				Would something like this do the trick?
Code: Select all
local sRecursionLoop --(sic)
on mouseUp
    put 10000 into sRecursionLoop
    doSimulation
end mouseUp
on doSimulation
    subtract 1 from sRecursionLoop
    if sRecursionLoop > 0
        send "doSimulation" to me
    else
        answer "fertig"
    end if
end doSimulation
 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 6:16 pm
				by Joerg
				Hi mwieder,
thanks for your hint.
Unfortunately it also doesn't work. I always get the same error message.
In the meantime I think, a high level of recursion is not possible with Livecode. I think, the suggestion of Dixie, to eliminate recursion e.g. by using repeat loops is the best, maybe the only way to loop through long tasks. Maybe it is anyway a better application design. I will try this for my simulation.
Best 
Jörg
			 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 6:29 pm
				by mwieder
				Ack! Sorry... I should have tested first.
Change
to
Code: Select all
send "doSimulation" to me in 0 milliseconds
That way the send command will execute at the end of the doSimulation handler instead of in the middle.
 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 7:22 pm
				by Joerg
				Hi mwieder,
YOU ARE GREAT!!! THIS IS ACTUALLY THE SOLUTION!!! Maybe you can explain why?
THANKS TO DIXIE TOO! I think you meant the same with your solution --wait 0 milliseconds
Best 
Jörg
			 
			
					
				Re: recursion limit
				Posted: Wed Jun 06, 2012 7:34 pm
				by mwieder
				Yes, I think Dixie was suggesting the same. Well, here's the thing:
You kept saying recursion, but recursion proper didn't really seem called for here.
The simple change I implemented instead is to have the doSimulation function process its data, then queue up another invocation of doSimulation.
When it's done (the counter reaches zero) it no longer queues up another call.
The recursive approach looks like
Code: Select all
doSimulation->
  doSimulation->
    doSimulation->
      doSimulation->
...etc
and never reaches the end of the first call to doSimulation before the recursionLimit is reached.
The queued approach is more like
Code: Select all
doSimulation
doSimulation
doSimulation
...etc
since the "send in 0 milliseconds" command doesn't take effect until after the "end doSimulation" is reached. Thus there's no actual recursion, just a repeated handler.
Using this same technique you can set timers as well:
Code: Select all
on repeatedAction
  -- implement a repeating 200 millisecond timer
  if the mouse is not down then
    send "repeatedAction" to me in 200 milliseconds
  end if
end repeatedAction