(race scripts {} for first finishing value)


A goofy block I made. The reason why I'm doing call (this [script V]) ... :: reporter control is because I set (... ((a...)) ... :: control) to be static. (surely no one would want dynamically place inputs in my block, right? Right?)

I took inspiration from JavaScript's Promise.race(...). That's all I think I want to say about it.

I was gonna just do a <(b) ≠ [0]> but then I realised the block might hang for scripts that return 0

That's clever. Alas, Snap!'s scheduler doesn't do real time slicing; it relies on explicit yields that Snap! carries out at the bottom of every loop iteration. So if the first script doesn't have any loop blocks (for example, it uses recursion instead) it'll win the race even if it actually takes more time than the second script.

Is this, like, a design flaw as I understand? Not meaning to insult your beautiful programming language, just asking...

No, it's a deliberate choice we inherited from Scratch. It means that you can say
untitled script pic (6) untitled script pic (7)
and get a perfect circle instead of a random walk. It also means that programs have deterministic behaviors, which helps a lot in debugging.

The principle of a process yielding only at the end of a loop iteration is indeed helpful for making program execution (more) predictable, thus simplifying debugging. There are limitations to its implied determinism though:

  1. If a process runs for 0.5 second without yielding, it will be forced to yield - run time tends to vary between systems, and even between trials;
  2. A program may be coded so as to act on randomly timed events.

So, in applicable cases, it may still be advisable to protect critical sections from process switching during at most 0.5 second, using untitled script pic 294. If a critical section needs more than 0.5 second of runtime, different (supplementary) protection mechanisms (e.g. semaphores) may be applied.