recursion limit

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

recursion limit

Post by Joerg » Wed Jun 06, 2012 11:09 am

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!

Dixie
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1336
Joined: Sun Jul 12, 2009 10:53 am
Location: Bordeaux, France

Re: recursion limit

Post by Dixie » Wed Jun 06, 2012 11:20 am

Would 'send in time' help with what you are trying to do ?

Dixie

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

Re: recursion limit

Post by Joerg » Wed Jun 06, 2012 11:37 am

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

Dixie
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1336
Joined: Sun Jul 12, 2009 10:53 am
Location: Bordeaux, France

Re: recursion limit

Post by Dixie » Wed Jun 06, 2012 11:51 am

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

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

Re: recursion limit

Post by Joerg » Wed Jun 06, 2012 12:00 pm

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?

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

Re: recursion limit

Post by Joerg » Wed Jun 06, 2012 12:15 pm

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

Klaus
Posts: 13820
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: recursion limit

Post by Klaus » Wed Jun 06, 2012 4:05 pm

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

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

Re: recursion limit

Post by Joerg » Wed Jun 06, 2012 4:45 pm

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

Klaus
Posts: 13820
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: recursion limit

Post by Klaus » Wed Jun 06, 2012 5:20 pm

Hi Joerg,

sorry, no idea.


Best

Klaus

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

Re: recursion limit

Post by Joerg » Wed Jun 06, 2012 5:40 pm

Hi Klaus,

thank you

Best

Jörg

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: recursion limit

Post by mwieder » Wed Jun 06, 2012 5:50 pm

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

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

Re: recursion limit

Post by Joerg » Wed Jun 06, 2012 6:16 pm

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

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: recursion limit

Post by mwieder » Wed Jun 06, 2012 6:29 pm

Ack! Sorry... I should have tested first.

Change

Code: Select all

send "doSimulation" to me
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.

Joerg
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 21
Joined: Sun Dec 20, 2009 12:35 am

Re: recursion limit

Post by Joerg » Wed Jun 06, 2012 7:22 pm

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

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: recursion limit

Post by mwieder » Wed Jun 06, 2012 7:34 pm

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

Post Reply

Return to “Talking LiveCode”