đ Recursive, Asynchronous Layering: What Shell Scripts Teach Us About Program Architecture
2025-09-18
The 'ticking' property of 'container parts' sounds like a useful guarantee for reasoning about async computational graphs (sections 3 - 4). So leaves have to be a function that returns, but containers can sit around listening for inputs.
I've been struggling with the compositionality of String -> String functions for expressive social simulation. This sort of control flow architecture will help.
$4
- Routes messages to appropriate children according to wire table
It sounds like the wire spec is really a [Sender, Receiver, Condition] entry. 'direction' is determined by the container/leaf-ness of Sender and Receiver. But we should write down a rule for whether the wire will transmit or not.
in general: I consider units of software to be more primitive than âfunctionsâ. A Part is ready to run if it has any messages in its input queue. When it is chosen to run, it might produce zero or more output messages and queues them up on its output queue. The Container routes the output messages, then loops around again to check if message routing has caused any other child parts to become âreadyâ. It does this over and over again until there are no inputs on any child queues and there are only messages queued up on its own output queue. I call this repetition âtickingâ. Operating system Dispatchers() do this, but they set a timer to interrupt a long-running child and to return control back to the Dispatcher(). In the PBP case, one is simply building a program, so preemption isnât required (itâs âjust a bugâ to have a too-long-running part), hence, we can whittle away a lot of hardware and CPU cycles and make the whole thing more âefficientâ. ⌠back to my use of the word âfunctionâ - âfunctionsâ imply a hard-wired routing policy, i.e. callee must /always/ send info back to the caller. I contend that it is important to be able to /not/ hard-wire that routing policy in /all/ code. IOW, a âpartâ is something more-primitive than a âfunctionâ, in my mind.
I donât yet grok what is meant by [Sender, Receiver, Condition]
. As soon as I see the word condition
my neurons see âstate machineâ (or statechart). IMM, âwiresâ (arrows) are tubes through which data flows. If thatâs what is meant, then I donât get it yet. If thatâs not what is meant, then I donât get it yet. Hmm, mullingâŚ.
I learned the word âtickâ from a colleague who is building robotics with ROS.
FYI, âwiresâ can only be defined in Containers. I donât/canât care whatâs inside Leaves.
I'm seeing the distinction between Containers, Parts, and Leaves more sharply, thanks. I agree it's a good idea to eradicate 'function' in this context b/c it could mean either an ideal function (with no stateful beliefs like the input/output queues), or a function on a call stack (which drags in conventional imperative beliefs about the runtime).
I think the Container and the list of wire specs are the same thing, up to guarantees about which parts ought to eventually be ready, i.e. the implementation of ticking. (But this is where I need to read up on propagators for real.) I'm not sure what the utility of more than one Container is.
I'm not sure what the utility of more than one Container is.
Architectural layering. Isolation of data /and/ control-flow. LEGOÂŽ-like parts that snap together. You can create a large system which is simple enough to understand at every layer. âFunctionsâ promise that kind of composability, but, the underlying âblockingâ nature of function calling (caller must suspend waiting for callee) hampers pluggability. In my eyes, current software practices based on code libraries lead to bloat and to fragility and increasing complexity and to gotchas. Analogy: the âidealâ way to build programs would be to create multiply-threaded architectures and use 1 Arduino (or other small machine) for each thread in a program (i.e. no operating system or other bloatware needed). If I were to build a system like this with 1,000 Arduinos, Iâd find some way to group them in a hierarchical fashion (think ORG chart in business, and, middle-management) and this leads to âmultiple Containerâ thinking. This is what most programmers think that they are doing, but, I contend that they are not because of the hidden gotchas that function calls/returns entail.
Thank you for the idea of a "wire table" -- might have just knocked loose some things I've been stumbling on in my head.