The define-as-you-go interface

WARNING: contains philosophy; use with caution

The following is rather philosophical. Such philosophical discussions of human-computer interfaces can easily fail the “not even wrong”-test. The counter-argument is that (outside of mathematics and physics) the more fundamental an idea is, the more vague it tends to be. I think there’s a germ of meaning here, and such discussion is necessary to unpick the glib “can’t you just X, this is micro optimisation” arguments thereby explaining why a class of tools are valuable.

A philosophy

I have recently developed an interest in the idea of the define-as-you-go interface. I would argue that this philosophy is well-embodied by emacs.

These ideas influenced a library I wrote for zsh, Zshnip (adapted from work by William G Hatch), and some convenient glue code I wrote for yassnippet in emacs makes use of this idea.

A problem: later means never

Often, while carrying out tasks, one thinks of things that could make the task easier to do.

In general, it is too much effort to implement these optimisations when one thinks of them. Further, one rarely gets around to implementing them later, not least because one often forgets the idea.

A way around these impediments is to use systems that allow you to carry out some form of automation as part of what you are doing.

A risk: the dangers of yak-shaving

The problem with automating-as-you-go is that the automation can take a long time. This risk is a popular topic for glib jokes. Such arguments can fail to take account of:

  • The motivational effect of “mastery over your work”
  • The demotivation effect of continued “paper cuts”: slight annoyance that over the course of a day can sap your will to work (and live)
  • How something being made easy changes how one interact with it

Treading the line between risk and benefit

The yak-shaving effect is real. However, it is possible to provide tools that allow one to “automate now” while also lessening the potential costs of yak-shaving.

Such tools can:

  • Make the act of automating as easy as possible (in practice, this is achieved by removing boiler-plate steps)
  • Reducing the power of tools and providing domain-specific-languages to stop people going down too much of a rabbit hole.

The first point is well-illustrated by comparing writing an emacs lisp function to writing a plugin for an IDE like, say, eclipse.

The second point is illustrated by tools like keyboard macros, vim’s mapping system and regular expressions.

Some practical examples


Zshnip and yas-edit are pretty much the same tool but for two different environments.

The idea behind these tools is that one:

  • Has a reduced-power programming language that only allows you to insert strings
  • Makes it trivial to define new strings to insert (there is a two keypress overhead for doing so)
  • Reduces the memory-load of using these tools by allowing people to guess what substitutions exist. Over time users may grow their own “grammar for substitutions” (e.g. all snippets related to git between with “g”, “rm” stands for delete in different contexts, etc).

Emacs lisp functions

Emacs lisp is a full-powered programming language, so it is difficult to argue it is of reduced power. However, even amongst turing-complete languages there is a degree of “rearrangement of which operations are easy”: sed is turing-complete but in such a way as to make string processing easy but addition hard.

There are trade-offs in the emacs lisp language that make it good for automating as you go:

  • You can call emacs-lisp functions directly while editing in emacs – this reduces the amount of configuration necessary before you can use newly-built tools
  • The emacs-lisp language makes copious use of global state. See, for example, the save-excursion and with-current-buffer macros. Global state makes it easier to define simple automation functions and test parts of these functions by hand: the functions that you use while editing are those you use while scripting, and there are no parameters that you need to learn.
  • One can evaluate lisp code from anywhere within emacs
  • It is very easy to look up documentation from within emacs.

Microsoft office macros

A criticism of the Windows Desktop Environment is that it is difficult to automate anything. Though this is true of much of the environment, it is not really true of Microsoft Office which has from quite early-on provided a simple and flexible automation language, as well as tools to automatically generate code in this language.