Befunge, but readable
github.com/m-ender/hexagony made the rounds of the internet yesterday, and caused me to swap in an old interest of mine that I've flailed ineffectually at in the past (e.g. twitter.com/akkartik/status/1238349948074070017): a way to display a program that makes its large-scale structure really obvious (rather than obfuscating it as Befunge does).
One problem I have with Befunge (not the one you're thinking of, ha) and other fungeoids [1] is that you have a bunch of static information about a program visible in 2D on screen, but a key piece -- the stack -- is invisible. The question I keep returning to is how one might go about making the stack (or any other run-time state used by the program) visible without just bolting it on on the side. This time around, I got hooked on the following metaphor. Imagine a spaceship that contains some data, sets out on a voyage across an infinite 2D plane, and performs various operations depending on the objects it collides with.
Example 1: The space ship contains a row of boxes. Colliding with a number pushes a box on to the nose, colliding with an operator operates on the 1 or 2 front-most boxes in the front. This is a way to display a stack, but a stack in isolation doesn't seem to scale well to larger programs.
Example 2: The spaceship contains a number. Colliding with the BF-inspired primitives +
and -
[2] causes the number to be incremented and decremented, respectively. Now build addition out of it. Zooming into a number n
shows it to be a loop of n iterations. When the spaceship collides with n
it loops through n times, and the number inside it has n added to it. At a high zoom, you see the spaceship loop n times before exiting the "solar system". At a low zoom you see the spaceship exit instantaneously with n added to its value. Now you can imagine a reduce operation as a series of solar systems that the spaceship visits one by one.
Example 3: The spaceship contains a binary heap to insert and delete elements from depending on objects it collides with. Zooming into any single collision reveals the tree structure to be the "space" that a smaller spaceship containing a single number bounces among.
Two properties that seem important from these examples:
- A hierarchical nature where space and spaceship are duals, and zooming in and out causes them to turn into each other.
- Rendering the state of a spaceship needs to be extensible[3]. We need to leave Befunge's ASCII behind.
At the largest scale, state machines feel like a really powerful way to represent the state within a spaceship. I often find them to be the outermost architecture of a large program. But to actually find the state machine I have to flail around for a long time. If we could use some visual paradigm at the largest scales but zoom into text as needed, programs might be much more comprehensible.
[1] esolangs.org/wiki/Fungeoid
[2] en.wikipedia.org/wiki/Brainfuck#Language_design
[3] Like in my old Pong demo: handmade.network/snippet/1561
“... A hierarchical nature ...”
FWIW, I strongly agree with this phrase. A minor change in POV might make this whole problem simpler...
We need notations that embrace hierarchy and relative-ism. Lisp lists, UNIX relative pathnames, StateChart nested machines, Kinopio “/”, HTML links, Dave Ackley all swirl around this flame... Force-fitting 4D reality down into a single 2D notation causes self-imposed accidental complexity (epicycles). We need to be thinking in terms of trees of stacks, trees of CPUs/machines/phones, trees of messages, etc.