Dec 29, 2022
A year of freewheeling apps

Over the course of 2022, I've found myself gradually programming in a certain way that has been working really well. Here, let me show you a few examples, see if you can spot the pattern:

  1. A plain-text editor where you can also draw line drawings.

    Screenshot showing text interspersed with a line drawing covering the
whole window width (48KB)

    Minimal dependencies, easy to build, runs anywhere you can install apps without asking permission, thoroughly tested, designed above all to reward curiosity about its internals.

  2. A different way to draw polygons. Old way:

    Drawing a square by specifying two points and one side of the resulting
line (200KB)

    New way:

    Drawing a square by specifying a centroid and vertex (200KB)

    First of a sprawling family tree of over a dozen forks of the original editor.

    Family tree of 9 forks, showing relative complexity of each along the x
axis (32KB)

    (Image drawn using itself, of course.)

  3. The Pong fork. Baking the editing environment into other apps for a self-contained curiosity-rewarding/forking experience.

    (Notice the extensible graphical logs. It takes very little code to augment debug-by-print. This work stemmed from the Handmade Network Wheel Reinvention Jam)

  4. Using the editing environment to debug the editing environment. (More tools should support a command palette; it's the best of commandline and GUI worlds.)

    Another graphical log, this time for the editing environment itself,
showing the command palette state changing in response to keystrokes (200KB)

  5. Pivot: making changes to programs as they run. They maintain state even after a crash (the red error on the left).

  6. LuaML, a box model over an infinite 2D surface that you can pan and zoom without restriction. Built in the live style, of course.

    (You can edit each text widget, and scrolling within a widget pans the whole surface. This took me a couple of tries to boil down to a reasonably elegant implementation.)

  7. Pulling LuaML “into the left window,” the editing environment.

I've found myself calling these freewheeling apps to myself. They're freewheeling in two ways. First, they're easy to get started with so you can be off doing your thing. Second, they stay freewheeling over time. They don't cramp your style with constraints after you've gotten suckered into adopting them.

“You want me to trust your binaries? I'm just not ready for that commitment man. Do you have a rock-solid build process that's guaranteed to work on my machine? I'd like the option to look at what you're up to when I feel like it.”

“It autoupdates twice a week? I'd rather not spend time tracking down what change broke my habits, thanks.”

“1GB install? What if I'm in, you know, the other 95% of the planet?”

“You have a PR submission process? How lovely for you. Hey, how about I just publish a fork, and you take what you want. (I love getting comments, though.)”

“I don't want to remember a bunch of idiosyncracies about your language and app. Can you just give me good error messages when I mess up? Just don't harsh my buzz about portability, compatibility constraints and whatnot.”

Replace “I” with yourself, dear reader. These apps should work anywhere (except mobile platforms), be easy to try out, easy to edit in place, and easy to subvert if you dislike a design choice. I'm going to continue improving the hacking experience, and I want to support forks in staying up to date with my changes. Unfortunately they require a little bit of programming experience for now (particularly git), but it should all seem pretty familiar regardless of what languages and tools you've used in the past. And if they don't, feel free to reach out. I welcome questions.


A lot of the bang here comes from the stack I'm using: the Lua programming language and the LÖVE game engine for Lua. You don't have to use Lua and LÖVE to be freewheeling, I think, any parsimonious stack designed to be portable and easy to build will do. But if you have another candidate that meets those criteria, I'd like to see it.


* *
Nov 30, 2021
Linear reading and the Silfen Paths

I spent the pandemic year reading a lot of Peter Hamilton. I wouldn't necessarily recommend it; they all blur together after a while, and I start to wonder if they aren't perhaps all the same story…

Regardless, the first Peter Hamilton I read, Pandora's Star, still sticks with me for a motif that didn't come together until right at the end: the Silfen Paths. In this universe humanity has portals that can span light years, often conveying train service between star systems, but there are occasional legends of an older interstellar network by an ancient alien civilization. Needless to say, our intrepid protagonist manages to get on this network. And suffers years of privation and amazing adventures (while everyone else in the novel is moving the story forward) before coming out the other end. Unlike the portals created by humans, the Silfen paths don't contain abrupt transitions between two points in space. Things blend together more gradually. Also unlike portals, the Silfen Paths aren't in the traveller's control. Instead, to go forth on the paths is to open oneself to the new, the unexpected. Extreme heat and cold. Danger. The occasional prancing Silfen who'll happen upon you and help you out, but who doesn't quite seem to get the idea of “home,” or that you're trying to get there, before outpacing you again, inevitably leaving you behind to find your own path through the maze.

Read more →

* *
Jun 13, 2021
Mu's neighborhood

My goal for Mu is software that is accountable to the people it affects. But it's been difficult to talk to people about Mu's goals because of the sheer number of projects that use similar words but lead to very different priorities and actions. Some of these I like to be associated with, some not so much.

if you care about making software accountable

Read more →

* *
Dec 30, 2020
The Mu computer in 2020

There are two ways of constructing software. One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method requires a willingness to accept limitations, and to compromise when conflicting objectives cannot be met.”
C. A. R. Hoare

It seems to me that modern computers trap people in a vicious cycle. Compatibility guarantees breed complexity over time as the world changes. Complexity is managed by introducing layers of abstraction. Abstractions introduce new compatibility guarantees. Over the decades this vicious cycle leads to even professional programmers understanding only a tiny fraction of the software infrastructure that runs their computers. As a result, our world is increasingly captured by software that is unaccountable to people.

For several years now I've had a vision for a computer that allows anyone to audit its inner workings, where any operation can be decomposed strictly into a parsimonious combination of simpler operations, terminating without cyclic dependencies or circular reasoning at some ground level. Ideally it would do this in a way that rewards curiosity, leading to a virtuous cycle where an order of magnitude more people grow to understand how their computer works as they use it.

Nowhere in this picture are compatibility guarantees, version numbers or forced upgrades. At any point your computer should be internally consistent and free of known historical accidents. Even if this means upgrades are more work and so more infrequent, and that our computers must be slower. Or do less. That seems like a worthwhile trade for a more sustainable world.

At the start of 2020 the state of the Mu computer looked like this:

Read more →

* *
Mar 15, 2020
Mu: The first 6 years

Over the last few months I've written up in one place the entire argument for—and comprehensive description of—what I've been working on since 2014. It will be published in the proceedings of the Convivial Computing Salon. From the call for submissions:

In Tools for Conviviality [1973], Ivan Illich said, “I choose the term ‘conviviality’ to designate the opposite of industrial productivity… Tools foster conviviality to the extent to which they can be easily used, by anybody, as often or as seldom as desired, for the accomplishment of a purpose chosen by the user… People need new tools to work with rather than tools that work ‘for’ them.”

We were promised bicycles for the mind, but we got aircraft carriers instead. We believe Illich’s critique of the damage to society from technology escalation offers a fresh perspective from which to discuss the pathologies of modern software development, and to seek better alternatives.

An inspiring theme. My response: “Bicycles for the mind have to be see-through.” Get it? When I look over at my bicycle I can see right through its frame. I can take in at a glance how the mechanism works, how the pedals connect up with the wheels, and how the wheels connect up with the brakes. And yet, when we try to build bicycles for the mind, we resort to “hiding” and “abstraction”. I think this analogy has a lot more power than we credit, a lot more wisdom to impart if we only let it in. I think conviviality requires tools with exposed mechanisms that reward curiosity.

I've been trying to falsify this hypothesis for 6 years. There are still large gaps to investigate, but so far it's holding up. Read on → [pdf; 25 pages]


* *
Oct 15, 2019
Mu: Sketching out a minimal system programming language

In the previous post, I described what my new hobbyist computing stack looks like today, and how the design decisions seemed to accumulate inevitably from a small set of axiomatic goals. In this post I describe some (far more speculative) future plans for Mu and try to articulate how the design process continues to seem pre-ordained.

(Many of the sections below outline constraints before describing a design that mostly fits them. This flow is inspired by Christopher Alexander's “Notes on the synthesis of form”.)

Read more →

* *
Oct 14, 2019
Mu: A minimal hobbyist computing stack

It is far better to have an under-featured product that is rock solid, fast, and small than one that covers what an expert would consider the complete requirements.”
Richard Gabriel's best summary (pg 219) of his essay, “Worse is Better”

Over the past year I've been working on a minimal-dependency hobbyist computing stack (everything above the processor) called Mu. The goal is to:

  1. build up infrastructure people can enjoy programming on,
  2. using as little code as possible, so that people can also hack on the underpinnings, modifying them to suit diverse desires.

Read more →

* *
Mar 16, 2019
Four example projects

Most kinds of power require a substantial sacrifice… By the time someone has acquired it, he has also matured to the point where he won't use it unwisely.
— Ian Malcolm, “Jurassic Park”

It is impossible to form anything which has the character of nature by adding pre-formed parts.
— Christopher Alexander, “A Timeless Way of Building”

Lately I tend to program in a certain unconventional manner. A series of design choices, each seemingly reasonable in isolation, take me pretty far from conventional wisdom.

Read more →

* *
Feb 25, 2018
Nobody's just reading your code

A guest post by Stephen Malina, my partner in crime on Mu.

Most programmers agree that we don't read enough code. The interviews in Peter Seibel's book, “Coders at work” highlight a comical contradiction: almost all the programmers interviewed by Seibel recommend that others read code for fun, but none of them routinely do so themselves. Seibel even asked Hal Abelson (of SICP fame) directly about this phenomenon:

I want to dig a little deeper on this. You, like many other people, say programmers should read code. Yet when I ask what code have you read for fun or edification, you—also like many other people—answer that you read students’ code, which is your job, and review code at Google, which is also your job. But it doesn’t sound like you sit down of an evening with a nice printout and read it.

Read more →

* *
Nov 27, 2017
Delimited continuations in a statement-oriented language

I've been periodically wrestling with the concept of continuations for several years now, and have somehow never gotten comfortable with them. Looking back, I think this was for two reasons:

  1. Continuations are usually explained in the context of high-level languages with higher-order functions and lots of nested function calls. But continuations fundamentally subvert the notion of “function”. Operators like ‘reset’ looked like functions, but had “spooky action at a distance” effects that were hard to reason about.
  2. I had trouble finding real-world programs where continuations are more expressive than regular recursive function calls with well-designed data structures. For example, classic back-tracking problems like the N-queens problem have elegant solutions that don't require continuations. Were continuations just a low-level primitive for building more high-level tools like generators (‘yield’) and exceptions? Building fluency with a concept requires developing an instinct for when it's applicable.

Read more →
* *
RSS (?)
twtxt (?)
Station (?)