I have been exploring what happens when notebook c...
# share-your-work
t
I have been exploring what happens when notebook cells are able to rewrite their own source code which combines with self-serialization nicely. This enables UI components to write back their changes, which are persisted on forks. I have generalized this to an insane degree and the result is I am finally able to build very nice widgets Visual Basic style. tomlarkworthy.github.io/lopebooks/notebooks/tomlarkworthy_daw.html#view=… When you move components around... you are actually programming in the sense of making source code changes, but no longer through a textual interface.
👍 2
❤️ 2
SOLID core, slop shell.
w
This is incredibly neat! Can you tell me more about how you went about implementing it?
t
Its been a 2 year process of reimplementing Observable notebooks as userspace modules inside the Observable Runtime (DOM friendly spreadsheet engine), with a ton of meta programming such that one module (exporter) is able to export the loaded runtime as a single HTML file, thereby creating a self-serializing Notebook programming environment that is local-first, binary compatible version of the hosted Observable platform (that I am a fan of). The tour is supposed to be the introduction: tomlarkworthy.github.io/lopecode/notebooks/@tomlarkworthy_lopecode-tour.html#view=… but its moved on a bit since then In theory, its literate programming so it should be self-describing, CMD + K will let you explore the module space, and each userspace module is a literate programming notebook with some high level explanations, and also there is an embedded AI you can ask how it works (robocoop-5), it knows, or you can ask Claude. Each bundle is multiple notebooks, you are only seeing the default one but you can open open on the page at a time. Some people did not like the notebook format so I start thinking about how to break out, also how to keep runtime values across exports. Recently I experiment with cells that write back to themselves, e.g. a structure like
() => widget(json)
is quite easy to parse and inject new json. So now widget can returns a UI component that self-writes is UI state as JSON and then when the runtime is copied the JSON goes with it. There is also binary File support if you want to do data the vanilla persistence way. So with that we can build widgets, using code or UI, and the environment handles serialization to a single file, or upload to ATProto. The Audio thing uses a UI widget that is itself a container of cells, so you can drag widgets around inside the grid container... and it remembers on save, including the UI state of the sub widgets which is very important for something like Audio tooling Building an Audio thing has been a parallel interest that I combine here. I always felt these should be more programmable, now the system can store UI state its good for creating programmable tools with fiddly knob twiddling you can save a hardcopy of. The primary repo is here github.com/tomlarkworthy/lopecode, technically there is a getting started here try the robocoop-5 AI its got its own wiki that hopefully makes it somewhat competent but I usually use Claude Code out of this repo and then it knows how to do advanced things. My motivation is I want immortal software that is highly portable and I think a single HTML with no network dependancies is a good format, and I like the reactive programming model of spreadsheets and it provides a solid base for live programming.
w
Oh wow, I've been trying to get something like this implemented for myself so this is really helpful and insightful. I didn't even know you could go about doing it this way! I really appreciate this and I'll try to dig in. Lately I've been trying to implement input language(s) -> AST / IR -> interpreter -> AST / IR -> output language(s) As an agent assisted way of specifying the code that I can inspect and build on. What I'd been stuck on was trying to figure out the reactive piece when trying to write my literate specifications and making them executable. This really clears up that piece for me.
t
Ahh! So I wrote a focussed technical piece on the source representation here tomlarkworthy.github.io/lopebooks/notebooks/@tomlarkworthy_lopecode-live-2026.html I called it
source-last
programming, I derive source code on-demand from the running runtime, at the lowest level from Function.toString(), this would be the IR you are describing. This removes a fair amount of coordination effort and makes more sense for live systems where the initially loaded code is not the final code listing of the program (you expect a live programming system's code to change during execution). Then you can have multiple languages too.
❤️ 1
w
Oooooh. Let me read my way through these, thanks so much Tom!