# Lisp Machine ideas, and Emacs

Several of Jonquil's features come from the Lisp Machines, the MIT CADR and
Symbolics Genera. This page says what those machines were, how Emacs relates
to them, and where Jonquil sits next to both.

## What a Lisp Machine was

A Lisp Machine was a whole computer where everything was Lisp: the operating
system, the file system, the network, the window system and your own
programs, all live objects in one running image. Any of it could be
inspected, changed or debugged while it ran, and the environment explained
itself. You could ask a key what it does, click a result to open the object,
and when an error happened the debugger opened with the stack still there.
The [Lisp Machine museum](https://github.com/htayj/lisp-machine-container-museum)
documents both systems in depth.

## How Emacs relates

The Lisp Machines had their own Emacs-style editor, Zwei (Zmacs), written in
Lisp and running inside that live system. GNU Emacs came out of the same MIT
culture and keeps the central idea at a smaller size: its core is a Lisp
interpreter, so the editor is a running Lisp program you can change from
inside itself. It runs as an application on an ordinary operating system,
though, so your files, processes and network aren't Lisp objects. You can
think of Emacs as the Lisp Machine's live, self-describing environment
without the rest of the computer.

## Where Jonquil sits

Jonquil heads the same way, and a lot of what it takes from the Lisp Machines
Emacs took first:

| Jonquil | Emacs |
|---|---|
| Describe Key, Key Bindings, Recent Keys | `C-h k`, `C-h b`, `C-h l` |
| The keys for the symbol at the caret, in the status bar | `eldoc` shows the signature, not the keys; Genera's mouse documentation line, which named each click's action on the thing under the pointer |
| The command palette (Cmd/Ctrl+Shift+P) | `M-x` |
| The locations list and F8 / Shift+F8 | `next-error`, xref |
| Find Usages in Project, by how each place uses the name and which var it names | `xref-find-references` (`M-?`); Genera's who-calls, resolved from each file's `ns` form rather than from a callers database |
| Save the layout, Use layout: name | `window-configuration-to-register` and `jump-to-register`; Genera's Select key brought up a whole activity |
| Switch to a recent tab, Go back to the tab used before | `switch-to-buffer`, most recent first |
| Switch to a recent panel, Cmd/Ctrl+Alt+1 to 8 for each panel | none built in: `C-x o` cycles windows; Genera's Select key, where Select L brings up the Lisp Listener, is where this comes from |
| The docs panel: a symbol's doc or a guide page beside the code, with Back, Forward and bookmarks | `describe-function` and the `*Help*` buffer, with `l` and `r` to go back and forward; Genera's Document Examiner, whose reading list and cross-references this follows |
| The Messages panel: agent actions, files changed on disk, connections, with an unread count | the `*Messages*` buffer, which keeps the echo area's lines; Genera's notifications and Converse are where this comes from |
| Time the form at the caret | `benchmark-run` |
| Count how often each line runs, beside the code | `profiler-start`'s call tree and `elp`, which sample or time functions; Genera's metering and `gcov`-style line counts are closer |
| Live console results: click to inspect, right-click verbs | none built in: CIDER inspects the last result; Genera's presentations are where this comes from |
| Trace the function at the caret, the Trace panel | `trace-function` and the `*trace-output*` buffer; CIDER's `cider-toggle-trace-var` |
| The Processes panel: the fibers your program spawned, Interrupt and Kill | `list-processes` (`M-x proced` for OS processes); Genera's Peek, which showed every process and let you arrest or kill one |
| Compare with the file on disk, git HEAD, another tab or the last Run, Take the other version here | `diff-buffer-with-file`, `vc-diff` and `ediff`'s per-hunk copy; Genera's Compare Files |
| The changed-form marks, Run the forms changed since they last ran | none built in: `diff-hl` marks lines changed since the last commit, not since the last eval |
| Change sets: the changed forms as a named, reviewable bundle you can apply to the REPL or revert | none built in: `git stash` and branches work on whole files and never touch the running Lisp |
| Show the last error's frames and locals | the `*Backtrace*` buffer (`debug-on-error`) |
| Break on error, Continue | `debug-on-error` while the error is live: `e` evaluates in a frame, `c` continues |
| Toggle Breakpoint (F9): pause at a line, live at once | `debug-on-entry` and Edebug's breakpoints (`edebug-defun`, then `b`), which instrument a function the same way |
| Step Into (F7), Step Over (F10), Step Out (Shift+F7) in forms holding a breakpoint, or every function of a tab instrumented for stepping | Edebug stepping (SPC to the next stop point, `o` to step out), within instrumented definitions |
| Retry, Edit and retry, Define and retry | none close: the Elisp debugger resumes a live stack, which an unwound one can't |
| Save World, Restore World: your session's data, one world per project | none close: `desktop-save` keeps buffers, not values; Genera's Save World wrote the whole machine, this writes data vars only |
| Open last session's replay: what the project evaluated last time, as a script in a new tab that runs only when you Run it | none close: `desktop-save` keeps buffers, not the forms you evaluated |
| Plugins written in Clojure, in the settings folder | Emacs Lisp packages |

Three things set it apart:

- **Your code runs in the editor's own runtime.** Emacs is extended in
  Emacs Lisp, a dialect separate from the language you're working in.
  Jonquil is written in Clojure on Jolt, and your Jolt code runs on that
  same runtime: inline in Jonquil's process for a loose file, or in a Jolt
  child process for a project (see [Dialects and runtimes](dialects/index.md)).
  The inspector, its history and Time the form look at your program's real
  values, not the editor's.
- **The debugger reads that runtime.** Jolt's `jolt.debug` keeps the frames
  and locals of a throw, and the Frames panel (Show the last error's frames
  and locals, see [Help and the inspector](help-and-inspector.md)) lists them
  for your own code: a frame opens at its line, a local opens in the
  inspector, and a form typed in the panel evaluates with that frame's
  locals bound. With Break on error the panel opens before the stack
  unwinds, and a form runs on the thread that threw, inside its bindings. It
  needs a Jolt release with `jolt.debug`. Emacs debugs Emacs Lisp
  well, but debugging Clojure there goes through CIDER and nREPL, a separate
  layer.
- **It stays a Clojure IDE.** Emacs turns everything into a buffer: mail, a
  shell, a file manager. Jonquil takes Lisp Machine ideas only where they
  help you write and understand Clojure code, and leaves the rest.
