Ivan Reese thinks out loud about the design of his esoteric graphical programming system.
Seven months of inking and switching later, a novel saw has been seen by all. In what interesting ways does said saw differ from Hest? In what ways are they similar? What even is Hest anymore? Listen on, Macduff.
I'm going to change the format of this show, for the next few months at least if not longer. We'll see! But stick around. There'll be more to come. I think. Probably! Maybe. Wait, where are you going? Aww beans.
I'm not trying to invent a new genre, I'm just trying to be the Estradasphere of visual programming.
If I'm not able to build Hest as it's currently conceived, what will it end up looking like? What gets cut, what gets saved — and in what order?
Marcin Ignac asked me the following on Twitter: "We are actually starting to think of abstractions/groups/sub-graphs in @nodes_io just now. Would you have any pointers to environments doing it well or wishes for a better way of doing it?" Yep, I've got wishes. Speaking of Marcin's Nodes project, this is essential reading: https://nodes.io/story/ Every visual programming language should have that depth of thought put into it, and should share that thinking out loud. Beautiful stuff.
Similar to the one about SpaceChem, this episode looks at another piece of prior art I'm drawing on for the design of Hest: the Live Schematic simulations built by my company, which are so much like a "Future of Technical Documentation" tool that it seems obvious to me that we need something similar for software development.
The only thing easier than making better tools for working with wires… is insisting that it'd be easy to make better tools for working with wires.
Listener question: What's the current plan for functions in Hest?
• A strange kind of not invented here. • "Easy to reason about" — quarter in the swear jar.
Listener questions? Send 'um in! • @spiralganglion • ivanreese@gmail.com Hest's data model is simple, very simple, but not so simple as to avoid a digression into AoS vs SoA. Properties are our springboard into the main topic: what is to be done about the interface? A sidebar is a recipe for spooky action, and I don't like spooky action, and I definitely don't like meat.
I have an idea for a feature called "accelerator functions", which are functions that define behaviour both within Hest itself and within the underlying runtime Hest sits atop (JavaScript, maybe someday "et al" too). Accelerators give you a way to write some heavily-constrained code that can run extra fast (directly against JS), but that can still be viewed and debugged as full-on Hest graphical code (which normally has a ton of overhead). This episode only discusses the feature in brief. The bulk of the episode uses accelerator functions as a lens to examine Hest's approach to static type checking, correctness guarantees, and the footguns you run into in their absence.
Speculating on nice affordances for programmers to hook into Hest's editor features.
Should nice, fun, playful tools and capabilities be built directly in the editor now? Or should those things be held back, waiting until the language model is robust enough to build them within it?
Point, dot, position? Edge, wire, path? And, whence Hest?
Issues with floats, Conal Elliott's FRP, 3:2 Pulldown, quantization, keeping things consistent whether running at "full speed" or in super slow motion.
Yes, I know it's pronounced "bez-ee-ay" not "bez-ee-er" but old habits die hard.
In detail, here's how Hest's evaluator advances the simulation state. This episode covers the simple parts. Next week, we'll look at the emergent chaotic bits.
Most games, and game-like software, use a constantly-running main loop to handle input, update their internal state, and produce an ever-changing result for the user. With Hest I'm taking a different approach, designed to reduce the idle power consumption to a minimum.
Zdog: https://zzz.dog Also — looking back on this episode after the fact (a few weeks after recording it, having spend the past few weeks thinking more about rendering), my thoughts on what would make for the best approach have changed. I'm already trying a new prototype with a different approach. This should serve as a reminder to myself (and such constant reminders are needed) that I ought to be very careful about speaking with undue certainty. I like to say that something *will* happen, when actually I just plan to attempt it, assuming my plans don't change. Of course, my plans always change. But that's the point of this podcast — it documents an ongoing design process. It's all talk of plans punctuated by small spurts of progress.
• Glamorous Toolkit's One Rendering Tree: https://medium.com/feenk/one-rendering-tree-918eae49bcff • Natto: https://natto.dev
Why not just make all data points take the same amount of time to convey along every path?
My blog post about different approaches to rewind: https://ivanish.ca/hest-time-travel Enso: https://enso.org Places to contact me with feedback: https://twitter.com/spiralganglion • https://futureofcoding.org/community • ivanreese@gmail.com
Caution: This episode may qualify as ASMR content. It might also qualify as irritating, sophmoric philosophizing. But as the previous few episodes have run aground on the muddy bank of the design space, I'm marking the occasion by establishing firmly that WHILST PERFECT IS NOT THE POINT, NOR IS GOOD. And now that that's out of my system, we're going to (in the upcoming episodes) jump back to the center and venture outward along an entirely new axis. Though that Ira Glass quote is fucking fire, hey?
Last episode, we looked at how the edges-conveying-points execution model leads to problems of synchronization. If you change some small part of your program so that it takes a little longer for data to traverse than it did before, then data leaving that small part will be behind schedule (so to speak) for wherever it needs to go next. Local changes cause non-local effects. This problems exists because, at the moment, a function (node / point) will execute the moment data arrives at it — so for a function to take two arguments, there needs to be two data points that arrive at that function simultaneously. Another issue comes when an in-development Hest program, which might be running at some much-slowed down speed, needs to pull in data from the outside world. Data from the outside world arrives at whatever speed it arrives at, slow-mo be damned. For both issues, I'm feeling the need to add sync primitives, queuing/buffering, and other mechanisms for temporal coordination. But I don't like the way these solutions feel, so I'm trying to find other things that feel different. This episode looks at one such different-feeling approach: get away from the idea of points travelling along edges! Instead, treat the edges like "fibers" (a la fiber optics), which assume the value of data conveyed to them and instantly convey that data onward. The data, no longer chopped into discrete points, no longer needs to be coordinated so strictly. Functions that are fed solely by these "fiber"-like edges will always have the most recent value available to them on every inbound edge, so they can produce a new output value the instant any single inbound value changes. No need to coordinate multiple pieces of data to arrive at a function simultaneously. Also — hi! I'm writing a much longer description than normal because my explanations within the episode are a little… weak. That's the deal. This podcast is just me thinking out loud, no plan, no script. It's doodles in the notebook. In the moment that I record, I am just talking extemporaneously, which is surprisingly hard. I have very little grasp on how much context I've already shared on previous episodes, or even how well I'm outlining the body of each new idea. I expect this disorganization is only going to get more pronounced as I get away from super high-level, welcome-to-Hest basics and dive more into the ideas I'm still unsure about and problems I don't really comprehend. We'll have to see! So in the future, if I feel I've done a mediocre job in the show, be sure to check the show notes for another crack.
Hest is a long way from finished — a long way from viable, even. It's still riddled with design issues. Let's take a look at one of the big ones: with the current design, there are no mechanisms for coordination. Introducing some of the most obvious coordination mechanisms would violate the spirit of Hest. How should that be fixed? Tune in next week!
Hest owes more to SpaceChem than any other inspiration. It's a beautiful little gem of a game, released by Zachtronics back in 2011. SpaceChem challenges you to design, develop, and debug complex systems, with an interface that looks a bit like a node-and-wire visual programming language. But the feel of playing it is wholly unique, and worth reflecting on and drawing from.
Data as player character. Continuity and intimacy. The well of video games. Putting your finger on the data and following it from birth to death. A patchwork quilt of understanding, versus a single continuous thread.
Virtual edges and pocket dimensions might be key pieces of a workable approach to abstraction, something that Hest sorely lacks.
Fully explore the space of your designs, even if it makes you into an infamous grump. Also, I sometimes make up jargon like Graphical Programming, and today we have another: Participatory Execution. Finally, Wallace & Gromit have their long-awaited debut on the show.
Grab the giant thumb, push it all the way to infinity at the top, or negative infinity at the bottom.
Functions and data, conveyance, points and edges, and execution with a mandatory, explicit notion of time and space.
Why am I making Hest? Who is it for? When did I start? When will it end? What is it now? Where is it going? And what of this podcast?
The term Visual Programming is a bit of a misnomer. My preference is Graphical Programming, though it is hard to overcome cultural inertia. Oh, also, welcome to the show.