Some tentative guidelines for GUI composability
You know how on TV every piece of software has a UI that is centered around doing something extremely specific and visualizing it in an intuitive and clear way? We all make fun of it, saying “have these people ever used a computer?” Sometimes it’s bullshit and sometimes what’s being visualized is something we couldn’t reasonably expect to have accurate information about but other times it’s like — why AREN’T our apps like this?
When I’m trying to solve a problem with a CLI, I write a tiny shell script whose UI is extremely specific to the problem I’m trying to solve, and I do it in a minute or less. I do it incrementally. My command line environment really does operate like a hollywood UI.
If we had good graphical composability and the ability to do the kinds of mashups in a graphical environment that are normal in a unix command line, any ‘power user’ (not just developers) could have a hollywood UI — not because some developer had used existing shitty UI toolkits to painstakingly develop something for their incredibly specific case, but because you can whip something up out of components quite quickly that will do what you want in a graphical way.
I think we could at least manage general composable interfaces like those shown in Apple’s Knowledge Navigator film, if not Starfire, if we tried. The catch is that commercial software (and indeed no software that is meant to be run by more than one person) can do this.
If the average GUI app was like the average shell function (i.e., made in minutes by someone who isn’t an expert, slowly honed over years, and never intended to be able to be used by anyone else), we’d basically have that future. The catch is to make doing that kind of stuff as easy as the unix command line is. We only don’t have it because GUI toolkits are so bad that it takes an expert a long time to write a shitty app — leading to a situation where GUI apps are required to be general-purpose, stable, and unexpressive, in order to make up for the labor that went into them.
A composable graphical system is possible, if we do it from the ground up. The Alto & Squeak environments get close, and so does Tcl/Tk’s ‘wish’ interpreter, but we’re not there yet.
Here are some guidelines for a potential composable graphical UI system.
- Widgets aren’t magic. You should be able to turn a widget of one type into a widget of another type by modifying some internal values & have it behave in a sensible way.
- Widgets aren’t magic. If you make a widget that combines two or more existing widgets, it’s of the same type as a more ‘primitive’ widget and works the same way.
- The window system knows about the environment and the user can view and live-edit the source of anything visible, with changes taking place on the next draw.
- The live editor is integrated with the environment and written with these same widgets. You can select and edit the code of any widget you can see.
- Widgets are prototypes but also part of a hierarchy. Edit a particular widget and it can be a template for new widgets. Edit its parent and changes apply to the whole class.
- Versioning is integrated with the environment and with the live editor. You can see all changes, revert to any, and navigate through the tree (even to previously-undone branches) or branch off part of a version tree as a new widget type.
- All widgets accept all messages and all events. Some widgets handle and respond to them. The default response is to ignore an unknown message, or a message targetted at a different widget.
- The normal way to produce an app is to create a widget by forking existing widgets and connecting their messages together, writing message handlers if necessary. Messages and default message handlers should be designed so that writing new message handlers is usually not necessary (or is trivial) for simple applications — useful apps can be created simply by directing messages between existing widgets, the same way useful shell scripts can be created simply by piping between existing commands.
- An app is composed of widgets, and is itself a widget. Other apps can cannibalize and fork parts of your app.
- Every object has a visual representation. Every visual representation corresponds to an object.
This post is also available on gopher: gopher://fuckup.solutions/0enkiv2/composability.txt
A prototype of a system based on these constraints is under development here.