Each thread has an ID and is defined as a function that loops forever, repeatedly printing its ID, and then sleeping 250ms:
["define", ["run-thread", "id"], ["loop", [".", document, "write", ["+", ["string", "Active thread: "], "id"]], ["sleep", 250]]],
So, how can a Wat thread sleep inside a loop? Why, with good ole delimited continuations:
To spawn a thread, I just wrap the call to RUN-THREAD in a prompt (which is just a unique object used as an identifier):
["define", "default-prompt", ["quote", "default-prompt"]], ["define", ["spawn-thread", "id"], ["push-prompt", "default-prompt", ["run-thread", "id"]]]
Where it gets interesting is the SLEEP function which captures the continuation up to the prompt, and sets up a callback with JavaScript's setTimeout that will reinstall the continuation later:
["define", ["sleep", "ms"],
["take-subcont", "default-prompt", "k",
["define", ["callback"],
["push-prompt", "default-prompt",
["push-subcont", "k"]]],
[setTimeout, ["wat-js-callback", "callback"], "ms"]]]
So, first, SLEEP aborts up to and including the default prompt using TAKE-SUBCONT. It receives the continuation in the variable K. Once it has K, it defines a CALLBACK function, that will reinstall the default prompt with PUSH-PROMPT, and then continue with K again with PUSH-SUBCONT. All that's left is to give this callback to setTimeout.
Then I can spawn independent threads:
["spawn-thread", 1], ["spawn-thread", 2], ["spawn-thread", 3], ["spawn-thread", 4], ["spawn-thread", 5]
Wat syntax certainly won't win a beauty contest, but it's already practical for adding concurrency and metaprogramming to JavaScript. Deployment is very easy. Include the single wat.js file, put together some code as JSON, and run it.












