Internalizing upvars? (open) & How to make a script wait for a message (solved)

I’m (re-)writing a library block that I’m using semaphores with, protecting the integrity of shared data within a multiprocessing environment. Wait times may vary between less than 1 millisecond and several seconds, or even more. Multiple processes may be waiting for the same semaphore too be freed.

I made a working implementation - it uses wait until (condition), which isn’t the most runtime-efficient block in the world though. I could free up runtime for other processes, replacing this by a test loop with a considerable time interval - at the price of extra wait time for the waiting process. Ideally I would like the script to continue after having received a message. Now Snap! has a when i receive hat block, but not an ordinary version - I wonder why not.

Does anyone have a solution I could try out?

To get a kind of passive wait you may try the continuation, i.e. use a publish/subscribe pattern.
Register a continuation of the waiting scripts and fire it when data is available (at stream update).

I'm not sure if a continuation does not involve implicit yielding. There are pieces of information about the threading model of the :snap: but nothing seems to be definitive nor official.

IMHO Snap uses a single processor model. So the "warp" is effectively a global critical section with an emergency timeout of 500 ms.
However, the risk of concurrent modification is low, as the context switch occurs only at the specific instructions in the code.

Thx 4 thinking with me! I tried:


, with:

, which would have been a bit problematic anyway, since the second block is a hat block, and libraries do not install hat blocks. Even worse … the continuation doesn’t work (perhaps because the script was stopped earlier).

So for now I’ll stick with my (sub-optimal) wait until solution for now - this is the application:


(it's call (promise) that may or may not take a very long time to complete)

I agree.

Most of the time, yes; still I can think of such cases. For library-purpose blocks I’m trying to reduce risks to a very higher degree, since I won’t usually be around if a future user runs into trouble.

untitled script pic - 2024-05-05T235418.382

untitled script pic - 2024-05-06T001722.166

Continuation is a strange beast...
untitled script pic - 2024-05-06T000123.297
.

untitled script pic - 2024-05-06T001234.439

You can say that again. Especially amazing: that stop (this script) is apparently ignored this way when the continuation is run! Once more you’ve proven to be a most inventive programmer, thank you! I’m going to try how this particular solution compares to wait for (condition).

If you don’t mind, I’m once more returning to the stream-with-upvar issue. As you may have read, bh warned me that with the approach I adopted from you (= replacing any external variable with its value) has its limitations. At first I thought this was not a big downside, but :I’ve since changed my mind. So I tried the opposite approach: replacing the upvar with an internal variable. To my frustration, I can’t get it to work:

Do you have a clue advto what might be the cause?

So this( continuation) is Say( "Found...


Yes, I was trying to export variable index.guid to the caller scope. But it does not work, yet...

Hmm .. yeah, I should have known. Apparently jens’ explanation didn’t make it all the way to my long-term memory, but I’m beginning to understand continuations a little better by now.

Regarding my request for help with replacing an upvar with a purely internal variable within a embedded script - if even you don’t know how to do it, it may be impossible. As a last resort: perhaps @jens knows?

Short explanation for jens

I am trying to (re)create a few blocks for the Streams library v.2, resembling list-HOFs - such as map (function) over stream (stream). The corresponding list-blocks have “magic rings”: if you press the ring’s right arrow,value, index, and list appear. I would like to have these at my disposal (with list replaced by the yet evaluated part of the stream, counting down from the current item), but I’ve got the impression that such is not feasible or otherwise undesirable. An alternative would be to use upvars that may be referred to within the embedded script, like in for (i) is (start) to (end) - however upvar run a high risk of getting messed up with deferred evaluation: between specification and evaluation, their values may be changed e.g. by other stream-HOF blocks using the same upvars. So I’ve been trying to replace an upvar by an internal variable of the HOF-block, but that isn’t working. Do you know if it’s possible at all; if so: how; if not: do you have a different suggestion? Thank you in advance!

As Polish folk wisdom tells :smile:
There were many musicians, but no one dared to play the dulcimer in Jankiel's (virtuoso) presence.