on livecode based idea (was Re: An idea on multithreading implementation)

Andre Garzia andre at andregarzia.com
Mon Jan 31 06:57:02 CST 2011


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.



More information about the use-livecode mailing list