Folks, >From working with livecode based servers for some year, I've drafted a little plan about co-routines. I don't have access to the engine internals, so when I think about solving a problem, I try to think in terms of the livecode interface that is exposed to us. Even though I would welcome threads, process forking and whatever, there is a way to create co-routines in livecode by extending some simple routines. What I will tell on this email will not add performance but it may add some advantadge on how to express things.
The problem with "wait with 0 ticks" and other send in time routines is that state is not preserved and that we cannot yield to the middle of a handler. Our problem is not switching handlers, our problem is state maintenance. So let us get the ball rolling. The first thing we need is a way to freeze a computation in time. By checking "the variableNames" (http://docs.runrev.com/Function/variableNames) and looping thru "the executionContexts" (http://docs.runrev.com/Property/executionContexts) it is possible to get an "instantaneous image" of what the engine is doing. Now, looping "the pendingMessages" (http://docs.runrev.com/Property/pendingMessages) as well would get what more is happening alongside the given script. We could then save all this information in what I will call for the lack of better term "the current continuation" (it is not a true continuation). So after the above steps we have a chunk of what is happening saved and stored. We now need a way to invoke a continuation, to restore a given piece of state. Right now, I think the only way to do it (or to fake it) is to use the debug routines. I think that is is possible to create a script runtime breakpoint, then, by execution it with the debug routines and stopping there, it is possible to manipulate the environment to load the state that was preserved before. This script should have the local and script local and global declarations needed for the given state, then we change all these variables to contain the data preserved from the desired continuation, we schedule the pendingMessages as well. Now the tricky thing is, we need an enhancement to the debugDo or some other debug internal command to start executing a script from a specific line. The executionContexts need to be used both ways, not only to peer on how we got to some place but set so that we can restore a previous state. If we could set the executionContexts and the next debugDo command would follow the natural computation from the current set executionContexts, we would be all set. So trough the use of a save state routine in pure LiveCode script we could save a continuation for later use. Using LiveCode powerful debug routines with some enhancements, we would then be able to restore to a given state in time. These two routines would be the basis that would enable us to do the following items: CO-ROUTINES (cooperative) A simple scheduler would save and restore states using cooperative threads where a given handler would call "yield" which would save his current state and then be restored to that exact point when the scheduler calls it again BACKTRACKING Some powerful decision making algorithms could be implemented. A script could branch into multiple paths to solve a problem and if found a wrong answer, it could chain call the restore state function effectively backtracking in time all its contexts and variables till the point of the branching where it could then follow some other branch. Backtracking is cool because once you found the correct decision path you were looking for it appears that you have a straight path since all the wrong options were erased due to backtracking. Think of it like solving a maze, every time you take a wrong turn, you erase everything until the given turn and then you continue from there to the other turn. When you solve the maze, you can see a straight path from your start position to the exit with not a single error. If you can't think of a practical use for backtracking, let me tell you two: 1) Error handling: Oops an error happened, backtrack until you solve it, no side effects. 2) Brute force anything: brute force something until you have the correct answer. CONTINUATION-PASSING STYLE WEB PROGRAMMING This is the big one for me. The main bad thing that hurt all web developers is that the web is stateless. There is a lot of code in anyones project to deal with sessions and finding where in the computation (in time) some user is. Requests all looks the same, you need to peek into cookies, hidden vars, urls until you find what you should be doing. This is a pain when trying to do things that need to happen in order with input from the user. For example, doing multiple page forms with runtime decisions about what to show is hard due to all the state maintenance. If we had continuations, we could simply save all the computation, present the page to the user and when he return, we restore the computation. This makes stateless web code look stateful, you can code like there is a single user going from point A to point B with no interruption. more info at: (http://en.wikipedia.org/wiki/Continuation-passing_style) CONCLUSION See with some simple additions to executionContexts so that it is settable, we can have so many goodies that would make our language so much powerful. If state can be saved and restored, it can also be manipulated and shared. This open up so many possibilities that simple threading or forking cannot compare. Even if this system is slow and not on par for doing fast game graphics, it still has its place. _______________________________________________ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode