-
Should reservations be ‘visible’ libside? (i.e. first-class, and differentiable from holding the unspecific Execution; or should they be simply an invisible property of Executions)
-
So, I'm back to thinking there's no need for reservations, and I can just do everything with ownership. But I'm running into some issues:
-
There would have to be some sort of semantic handling of syntactic indirection (ew); because
foo[] [bar[] [baz]]
and such would need to work … that is,foo
having ownership of our caller (so arbitrary interlopers wouldn't be able to interject in our conversation withfoo
) shouldn't preventbar
from talking with us in the meanwhile. However, that shouldn't then allow such interlopers to interject (such as afterbar
returns for the last time, but beforefoo
is resumed? idk.) -
How do I design around a common pattern like
stage [assign [locals] ‘foo’] *
? Okay, so that actually works, but. If an explicit unstage / resumption-point / consumption-point is inside nested layers of indirection? If we're handing ownership around as above, we can't just throw away all the ownership restrictions we've constructed? Or do we do exactly that, but re-instate them after the first resumption … hm. -
One of the fundamental problems with treating coproduction as an ownership issue, is that it requires conceptually unifying the ‘ownership’ rules and ‘staging’ rules. Somebody attempting to get ownership gets blocked until that ownership is available; whereas thus-far, somebody attempting to stage is not inherently blocked (whether or not that staging happens immediately isn't of relevance to the operation of ‘staging’ itself.) They're usually, instead, implicitly blocked (by unstaging themselves, and then only being resumed when the caller they handed themselves to, calls them again.)
Meanwhile, we obviously don't want queueing the staging of another currently-locked exec to involve explicitly blocking ourselves, the caller … which means we'd have to have some sort of queue of stagings that have been dispatched while it was locked. Which is no different than the current staging queue, or the slightly modified reservations queue. Fuck.
-
So, I guess that makes the goal: “How do we implement non-blocking[1] staging, while replacing the separate staging-queue and ownership tables with a single, unified system[2]?”
-
-
In my quest for queuelessness, I'm not sure what to do with ownership. I'd originally planned just to put the ownership of a given object to be stored on the object (and thus in the datagraph); but now I've realized that that makes it difficult to calculate Masks ... ugh ... crawl backwards from the object being looked at, checking for objects that are owned?
-
Which, in turn, requires backlinks in the data-graph, which I'd explicitly been trying to avoid. Perhaps I can do dynamic / temporary backlinks? (crawl tree and add backlinks on adding ownership to root object ... if backlinks exist to parent when updating object, update them ... when trying to crawl tree, if backlinks don't exist, you can abort immediately, knowing there's no sub-graphs containing the object in question? But all that just pushes the crawling-work upstream to
own()
-time.) -
Alternatively, perhaps I could retain the concept of Masks, but take out the global storage of them. They could act as a kind of cache; and then updates to ownership (canonically stored in the data-graph, but mirrored in Mask-caches on each stage ... but no, that would just be storing the same data simultaneously in two places >,<). Nope.
-
Okay. Fuck it. Going with a new Reservation
type. Decisions:
- They will be invisible from libspace (
Reservation
vs.Native
/Exec
will be similar toNative
vs.Execution
; anything taking anExecution
should take aReservation
as well.) - They can be electively created, but only with a
Node
(which, for the moment, can only be obtained from a syntactictarget
). Besides that special-case (for disordered-parameterization),Reservations
come from the hard-coded ‘call pattern’ (i.e. from the syntactica b
whena
has the nativeExecution
-receiver.)