Wait, the problem, and why it is important to solve

Mark Waddingham mark at livecode.com
Sun Jul 30 00:23:35 EDT 2017


So LiveCode has long has this feature called 'wait' - it is one of those 
seemingly innocuous things which, from the surface seems simple (it 
allows you to wait for something - it's great when syntax is aptly 
named!) however it is perhaps one of the deepest language features we 
have.

I think there is some confusion (or puzzlement) as to why I am a little 
hung up on it because, on the whole, the 'wait' command is not actually 
seen in script that much. Certainly it is part of some people's coding 
style (the one thing I love about LiveCode is that it promotes a very 
pluralistic style to solving programming problems), but on the whole 
many of us rarely if ever use it. Well, we *think* we don't use it.

The thing is that 'wait' is such an important feature to LiveCode that 
many pieces of syntax use it without you knowing! The pure mathematician 
in my likes classifying and counting things (hey its what we do!), so 
here is a reasonably complete list of the places the engine uses it 
(this list is alphabetic by source-file in the engine order):

    - it is used to provide the flash of the menu when a menu accelerator 
key is pressed

    - it is used to wait for uses of shell() to send back any data so it 
can be accumulated for return

    - it is used to wait for a return value from sending an AppleEvent on 
Mac (send and request)

    - *it is used to implement 'wait for/until/while ...' (kinda obvious, 
but hey, I was trying to be semi-complete ;))*

    - it is used to implement 'read ... with timeout' forms

    - it is used to wait for process death when you do 'kill'

    - *it is used to wait between beeps when you do 'beep <n>'*

    - *it is used to moderate the speed of 'drag from x to y'*

    - *it is used to moderate the speed of 'type STRING '*

    - *it is used to moderate the time between mouseDown and mouseUp when 
doing 'click at'*

    - *it is used to wait whilst a non without-waiting form of 'move' is 
invoked*

    - it is used in the mobile browser control to wait for JavaScript 
evaluation to finish

    - it is used to wait for mobile calendar UI modal panes to return

    - it is used to wait for mobile photo taking panes to return

    - it is used to wait for mobile contact UI modal panes to return

    - it is used to wait for mobile datetime/option picker modal panes to 
return

    - it is used to wait for mobile compose mail UI modal panes to return

    - it is used to wait for mobile media picker UI modal panes to return

    - it is used to wait for mobile fullscreen videos to finish

    - it is used to wait for mobile text message UI modal panes to return

    - it is used to wait inbetween vibrations when you use 'iphoneVibrate 
<n>'

    - *it is used to wait between frames for visual effects / 
transitions*

    - it is used in all forms of blocking socket commands (open, read, 
write etc.)

    - it is used to wait for blocking DNS resolution to finish*

    - *it is used to wait for 'modal <stack>' to finish (by closing the 
stack)*

    - *it is used (in libURL) to wait for evaluation of 'url <url>' to 
finish*

    - *it is used (in libURL) to wait for 'post to url <url>' to finish*

    - *it is used to wait for 'popup widget' to finish*

    - it is used by various other things in externals, and widgets and 
libraries to implement things which need to wait for something or some 
time in order to have something to return

Phew! The ones surrounded by '*' are ones which would make some sense to 
have working in HTML5. Almost all of these can be rendered in a form 
without 'wait', they just end up being *slightly* less useful or easy to 
use (e.g. get url -> load url, always use 'move without waiting', etc.).

So, first thing to point out, even without 'wait', if we manage to 
implement all the existing things which make sense in the HTML5 engine, 
'greenfield' (new projects) will work fine (as you avoid the things 
which don't work in HTML5), and a reasonable number of existing projects 
(particularly ones which are already written to use 'load url' rather 
than 'get url') will also work. However, there will still be a 
substantial number of existing projects which will not, without 
significant code changes.

One of the things we pride ourselves on is that (on the whole) an app 
written on one platform will work, largely unchanged on all the others 
(particularly if platform-specific features are avoided). However, we 
can't really keep that mantra, if something such as 'wait' is abandoned 
because it is deemed 'too hard to implement'. It means for any project 
targetting HTML5, you have to write in a different style, and avoid a 
reasonable number of features that many use day-to-day.

Now, if these features were 'just' things like 'drag' or 'click' or pick 
any specific (non-general language feature) that we have things wouldn't 
be too bad. However, 'wait' is a different kettle of fish altogether.

Wait is essentially LiveCode's implementation of 'async' - this is 
something that C# has (which is a much newer language than LiveCode - 
and its HyperTalk heritage); it is something JavaScript is in the 
process of adding. The simple reason is that event-driven coding is so 
ubiquitous these days (we've known its important for a long time) that 
other languages are gradually catching up to the need to have some way 
to do it easily.

Of course, async (i.e. wait) in LiveCode is not perfect - it is 
recursive, and not side-by-side (or 'round-robin' would be another way 
to put it) - and it is a little bit specific. However, on the whole, the 
fact that it exists at all *and* the engine uses it in various commands 
*does* simplify things.

So, 'wait' is important. Indeed, one of my hopes is that through getting 
wait to work in HTML5, we will also be able to *then* improve wait to 
bring it on par with other languages much more recent 'async' 
implementations. Indeed, my hope is that we can get to a point that code 
which needs to be written in a threaded/callback style now in LiveCode 
could actually be written without callbacks - this is the goal of the 
additions to JavaScript (due to node.js and its pure event-driven 
nature) - and if they can do it without having had a 'wait' 
implementation to build on, why can't we?

Anyway, the 'wait' beast in HTML5 has almost been slain (at least in 
thought). I think we almost have a solution which will require modest 
C++ code changes (which are doable without huge churn); and the rest can 
be done as a process that transforms the scripts we write. It might be 
upon further analysis, that another angle of attack actually makes more 
sense - compiling the current syntax to a bytecode, and using a VM which 
understands how to wait to execute it. To get performant code out, the 
asyncify algorithm / process would still be needed at some point; so it 
is merely a matter of ordering. At the moment, I *think* asyncifying at 
the script level will take less time to engineer and thus gets us to a 
fully compatible HTML5 engine quicker; however, we shall see what the 
next few months bring.

Warmest Regards,

Mark.

P.S. One other possibility I've toyed with is doing LCS->BYTECODE, then 
BYTECODE->ASYNCIFIED_JAVASCRIPT. The latter would be particularly easy 
if targetting browsers which have already implemented the new async 
JavaScript features. Since it looks like the HTML5 engine will only 
become truly widely usable when we move to WASM, this might well be a 
much more maintainable, and relatively quicker option.

-- 
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps





More information about the use-livecode mailing list