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