An Experiment in Structured Code Editing

One of the core experiments of isomorƒ is creating a new paradigm for editing code based around a few guiding principles:

  1. It is structured. The user is editing a syntax tree and not a block of text. This makes syntax errors impossible — code is always syntactically correct. Editing commands are semantic and the necessary peripheral syntax is always automatic (i.e., commas, braces, parentheses, keywords, etc. are all added wherever necessary).
  2. It is projectional. There is a layer of indirection between the storage format and the visual representation. The appearance of the code is flexible, personal, and mutable. Each user has her own lens through which to view code — regardless of which user actually wrote the code. This affects neither the storage nor the behavior of the code. It is a strictly end user experience, akin to changing the font of an eBook.
  3. It is propagational. Changes that imply other changes are made automatically. If you rename a function or argument, it is renamed everywhere. If you delete or add an argument to a function, a placeholder is added (or removed) everywhere applicable. Edits are treated as semantic commands and not simple ASCII character changes.
  4. It is keyboard shortcut driven. Despite the structure and visualization of code, the intent is NOT to move coding toward a visual mouse-click style input paradigm. The prevailing style of developer efficiency is based around mastery of powerful keyboard shortcuts and we support this model. The expectation is that code is still created via keystrokes — just that we can create a more powerful and semantic mapping from keystrokes to code.

Templates and Placeholders

Structured editing requires a complete semantic structure at all times. So starting from scratch cannot mean starting with a blank file. Placeholder structure must exist to give code a backbone before it is implemented. There is a need for something to hold the place for all the rich and wonderful types, expressions, and patterns that are soon to be created. In isomorƒ this is denoted with a ? symbol (inspired by the ??? function in Scala) that can represent either a type, pattern, or expression. (For those familiar, you can think of this as something like a bottom type.)

A function template, just dying to be implemented.

This structure means that deleting code (via the backspace key) will always bring you back to the ? as opposed to leaving you with nothing at all:

deletion in action

Cursor vs Focus

Another implication of structured editing is that there is no cursor in the traditional sense. You can highlight any element of the code, but you cannot put a cursor between or inside a word or control structure like you can with text. Arrow keys allow for code traversal.

a captivating navigation through a simple function

The shift key can be used to select multiple elements at once. Wherever sensical, multiple concurrent editing is possible.

why not both?

Editing

So how does editing work in this paradigm? Here is a rundown of some simple editing actions and how they appear in isomorƒ:

Expressions

  • enter creates a reference to any locally defined argument, function, or pattern.
  • ? creates a match statement with the selected expression as the subject. If the type of the subject is knowable, relevant case patterns will be enumerated.
  • ( calls/applies a function or constructor, making the selected expression the first argument. The application will be padded with ? to ensure the correct number of arguments.
  • = defines a new local function. Engages a naming dialog. New function will have two arguments by default.
  • 1 creates a first-order function reference.
  • > creates a lambda function. If knowable, the types will be populated.
editing expressions

Editing Patterns

  • enter creates an identifier. Engages a naming dialog.
  • ( creates a constructor pattern. Engages a select dialog.
  • _ creates an ignore/unnamed pattern.
editing patterns

Editing Types

  • enter provides a list of existing types from which to choose.
  • a creates a parametric/generic type.
  • > will convert any type to a functional type.
editing types

Editing Signatures

  • enter renames a function or argument. This rename will be propagated.
  • + adds a function argument. A naming dialog will engage.
  • backspace on an argument will delete the argument.
renaming arguments/functions; adding/deleting arguments

Clipboard Operations

  • x cut
  • c copy
  • v paste (works across simultaneous locations.)
cut, copy, paste

Clone

  • 2 will make a clone of an element of code. Similar to a copy then paste.
cloning saves you time

Swap

  • & swaps any two elements (of the same kind).
swapping code elements

We are excited to continue experimenting with this new editing paradigm. We predict that the grace and power of the system will only improve. Stay tuned for an upcoming release of specialized refactoring shortcut keys. Feel free to play around with the editing paradigm in our public sandbox and don’t hesitate to let us know what you think.