I spent some time the other day thinking about zippers and structural editors and I wanted to share some of the ideas, because they were interesting, so this is going to be a thread about that
Post
when we think about editors, the canonical example is a text editor, which is conceptually very simple. in the functional programming context, we often think of editors in terms of a structure called a zipper, which you can read about here:
the usual way of looking at a text editor through the lens of a zipper is to view the string/text as split in two, the stuff before the cursor and the stuff after, with the stuff before the cursor reversed
but the equivalent of this is hard to figure out for tree structures. the closest analog for tree structures has to pluck out an entire subtree, which isn't quite the same thing as splitting a string in two
you can massage the idea of splitting a string by saying well, you've "plucked" out a character from the middle, but i think this is a mistake. we're really dealing with distinct concepts and its useful to try to figure out how to understand their relationship
in particular, I think it's useful to think about the different cursor types that exist in terminals, especially in older settings
what i mean is the difference between vertical line cursors and underline/box cursors
historically, the underline/box cursor and the vertical line cursor had different meanings/usages
the vertical line cursor was an insertion cursor that indicated you were going to insert a character at the cursor position BETWEEN existing characters in the string
thats why it was a vertical line -- to fit between two characters. sometimes a subscripted ^ was used for a similar purpose
the underline and box cursors were whole character width because they would be overlaid on top of an existing character to indicate that the character would be _replaced_ and _overwritten_
if you've ever wondered what the "Insert" key on a keyboard is for, it's for toggling between insertion and overwrite ("overtype") mode
overwrite was the default for decades, because terminals were _typewriters_ and you literally couldn't insert at all
so early electronic terminals kept the overwriting as a default, and also offered an insertion mode with a key to toggle. this is also why backspacing sometimes seems to do nothing in terminal emulators except move the cursor to the left -- teletypes couldn't backspace either
the distinction between the Insert line cursor and the Overtype box cursor lines up rather neatly with the kind of zippers I mentioned earlier
text editing zippers are INSERT zippers, while tree zippers are OVERTYPE zippers
interesting!
in the case of a text editing zipper for overtype mode, that's pretty easy too:
it's not a pair of strings, but rather a string for the reversed stuff before the overwritable character, the character that would be overwritten with an edit, and the string after the character
but strings/lists are just a kind of single-branching tree, so strings should ALSO have an overtype-style zipper when viewed as trees, and they do: it plucks out an entire sub-list from the string