Dec 12, 2019
Layering optimizations that require extra state

(Part of a conversation with Luca Matteis)

Background

A few years ago, I built a text editor in an old version of my statement-oriented language called Mu.

The language was a little unconventional. It was purely statement-oriented, like Assembly or Basic. Every statement had just one operation, and its arguments had to be variables or literals.

The editor was a little unconventional. It was built up out of layers (1, 2, 3, 4, …) arranged so that layer 1 would build and run and pass any tests defined in it. Similarly, so would layers 1+2, 1+2+3, and so on.

Later layers added to the code of earlier layers using directives like `before` and `after` on labels. (A statement-oriented language really helps here.) But later layers never modified tests of previous layers. Layers monotonically accumulated constraints.

Layers were really helpful to convey the internals of programs to 12-year old kids. You can try them out for yourself (on Linux or a Mac, with a C++ compiler):

$ git clone https://github.com/akkartik/mu1
$ cd mu1
$ ./mu edit/001-editor.mu

At this point you should see a blank screen, and hitting any key should quit.

Now add a layer:

$ ./mu edit/001-editor.mu edit/002-typing.mu

At this point you see a blank screen and can type letters into it. Lines wrap at a specific column.

Hit `ctrl-c` to exit.

Now add a third layer:

$ ./mu edit/001-editor.mu \
       edit/002-typing.mu \
       edit/003-shortcuts.mu

Now special keys like tab, backspace and arrows work.

Add a fourth layer.

$ ./mu edit/001-editor.mu \
       edit/002-typing.mu \
       edit/003-shortcuts.mu \
       edit/004-programming-environment.mu

Now you get two text editor windows, side by side. You should be able to position the cursor in them using the mouse, and type on either side.

Again, hit `ctrl-c` to exit.

In this manner you can add more layers and see the entire teaching environment come gradually online. You can also run tests with each subset and see the number of tests gradually grow:

$ ./mu test edit/001-editor.mu
..........
$ ./mu test edit/001-editor.mu \
            edit/002-typing.mu
....................................
$ ./mu test edit/001-editor.mu \
            edit/002-typing.mu \
            edit/003-shortcuts.mu
...............................................................................................................................

Since each combination is internally consistent, kids can tinker with just the first layer by itself, spending as much time as they want to understand how it works. Once they feel confident they can add the next layer. Or they may just be using the text editor but dig into a specific layer when they want to say add a hotkey for themselves.


The problem

While layers were mostly very useful, and it was usually easy to figure out the right ‘joints’ to cleave a program at, I encountered a couple of more challenging scenarios, and I'll describe one now.

The naive way to build a text editor is to just render the entire screen after each keystroke. But of course this is slow. Particularly if the text editor happens to be written in a naive interpreted language that's slow to begin with. In response, it's natural to get smarter about which regions of the screen you redraw in response to different keys. But the optimization makes the code significantly more complex, and the naive approach is actually a nice introduction to text editors. Could we get the benefits of both sides using layers? Ideally layer 1 would have the naive redrawing algorithm, while layer 2 would have the optimizations.

Here's the code for the naive version: 002-typing.mu (html version)

And here's the optimized version: 003-minimize-prints.mu (html version)

After you've skimmed the html versions in your browser, try downloading the .mu files locally and opening them up in a `diff` browser. There are extra state variables that need to be threaded through the algorithm. I could never figure out a clean way to manage these when using multiple layers. Can Behavioral Programming do better?

Comments gratefully appreciated. Please send them to me by any method of your choice and I'll include them here.

archive
projects
writings
videos
subscribe
Mastodon
RSS (?)
twtxt (?)
Station (?)