Having experimented with the multi-stack environment, I’m now contemplating the elimination of anonymous stacks (stepLeft, stepRight, newStackRight, remStackRight) and instead switching to a system that only has the current stack, one hand, and a list of named stacks.
The motivations for this:
- A simple stack/hand combo, with “roll” (of current stack) and “juggle” (of hand), seems very expressive and convenient for the cases that are ‘near’ enough for short-term memory of relative structure. Anonymous stacks don’t introduce much utility in-the-small.
- The idea of multiple stacks for multiple tasks is great! But skipping between tasks isn’t something I often do in the short-term, and I don’t want to remember relative positions long-term. “Named stacks for named tasks” seems like a useful policy.
- In the few cases I do want to bounce between tasks, it is usually at integration points. But I can model promises/futures via fractional types; I can “make promises” to one task and “fulfill promises” in another, like creating a bundle of wires at the destination and running them backwards to the source. This would let me do more integration with less navigation.
- Named stacks make it easy to carry named extensions, such as “AOPadvice” (list of advice for explicit join-points) or “keyring” (list of sealer/unsealer pairs). Further, with named extensions, it should be easier to explicitly forward some useful extensions to applied blocks in a standard way.
- Named stacks are potentially more stable across code changes, extensions, and reorganization, i.e. no risk of a new anonymous stack breaking relative offsets.
If I make this change, the new environment will likely become: `
(s * (h * (ns * lns)))`.
Here `s` is the current stack. `h` is the hand (also a stack). `ns` is just a string, the name of the current stack. And `lns` is a list of (name*stack) pairs. By keeping `ns` in the environment I can more easily switch stacks without explicitly naming the current one. (I can also rename the current stack as a trivial operation.) Most of my blockless data-plumbing code will need to change, but that isn’t a significant problem – much of it will be lighter weight due to the simpler environment.
In addition to navigating stacks, developers could directly load/store/loadCopy/etc. on a stack by name. Named stacks can easily serve a similar role as variables – a place to dump objects that you won’t get back to for a while. It should even be possible to have multiple stacks with a given name in `lns`, using a shadowing model (i.e. always grab first reference to a given stack name). That could be useful for temporary names. (I can also provide a library of functions to statically assert that a stack name exists, does not exist, or is unique.)
An IDE could still render the named multi-stack environment, though exactly how it organizes the named stacks would be an open question. (There is no ‘obvious’ render like for a list of anonymous stacks.) Given a named stack, it might be useful to highlight all the words that operate on it.