flan/docs/REFERENCES.md
Joseph Ferano 57fe91f303 Five records become one, and every citation lands somewhere
FIX.org, NEXT.md, DISCUSS.org, docs/DISCUSS.md and the session handoff at the
root are one TODO.org now: 293 entries under seven subsystem headings, each
carrying an org keyword that says where it stands. A DONE entry is a few lines
saying what was decided and what that rules out; the reasoning that would not
compress — the embedding spike and the four reports the hand-written x86
backend was built from — moved into docs/BUILT.md instead, and its entries
point there in one line.

Every entry was checked against the tree before it got a keyword, and the
prose was wrong in both directions. Things the deleted files called open were
built: the first-evaluation stall, main being redefinable, macro parameter
lists, the type-limit constants, the array constructors, the byte fills,
inc/dec, the discard's fontification, the Emacs buffers, rt_die's _exit, the
backtrace surface, and the acceptance failure that could print and still exit
zero. Things they called done were not: the backend reports' no-plan buckets
had gone stale in the other direction, the value-dependent defvar was
superseded rather than built, and macro-expansion source locations are on an
unmerged lane, so that entry is NEXT and names the branch.

Every comment that cited one of the five by name now cites a heading that
exists, in TODO.org or in docs/BUILT.md. The session reports under
docs/handoffs/ keep naming the files they worked on, because rewriting them
would falsify what those sessions did; each carries a note saying where the
content went.
2026-09-21 21:05:48 +07:00

121 lines
7.6 KiB
Markdown

# Reference clones on this machine
Read the source, do not recall it. Every claim in this repository's notes that came from one of these
was read out of the clone, and the ones that were recalled instead have been wrong before — see
the corrections `TODO.org` records. When a note cites a file and line, it is because someone opened it.
All paths are under `~/Repositories`. Dates are the last commit in the clone at the time this file was
written (2026-09-13); a stale clone is still the right source for how a thing works, just not for what
its newest release does.
## The ones this language is built against
| Clone | Last commit | What it answers |
|---|---|---|
| `Odin` | 2026-07-10 | **The primary reference.** Memory model, containers, generics. |
| `sbcl` | 2026-09-07 | Conditions and restarts — what they should *mean*. |
| `zig` | 2026-09-12 | Comptime, build system, error handling, C interop. |
| `jank` | 2026-09-11 | A Clojure with native interop and a REPL into a running process. |
| `janet` | 2025-09-29 | A small embeddable Lisp. `varfn` and its reload story. |
| `raylib` | 2026-07-16 | The C library the FFI binds. **Note:** `vendor/raylib/raylib-5.5.h` in *this* repo is the committed header the bindings are checked against on every build; the clone may be a different version. It used to be whatever `vendor/raylib/web/` happened to hold, which is gitignored and therefore absent from a fresh worktree — the reason the header is tracked now. |
### Odin, specifically
Most of what this repository copies. Places already cited in the notes:
- `base/runtime/core.odin:369` — `Map_Info`. The type-erased container runtime: `rawptr` keys, cell
info for size and alignment, hash and equality as function pointers. This is why `Vec` and `Map`
here need no generics, and it is the thing that was **not** converted when generics
landed — `Vec` and `Map` are still type-erased, and a `$t` only reaches them as an
element or key type.
- `base/runtime/dynamic_map_internal.odin` — the map algorithm `(Map K V)` follows.
- `base/runtime/dynamic_array_internal.odin` — the same for `Vec`.
- `src/check_expr.cpp:470-510` — `find_or_generate_polymorphic_procedure`. The instantiation
cache: a polymorphic proc entity carries a `gen_procs` list, each call builds the concrete proc
type, and the checker scans for `are_types_identical` before generating a new `Entity`. This is
the machinery the generics spike copied.
- `src/check_type.cpp:173-200` — `FieldFlag_using` and `FieldFlag_subtype`. Odin's answer to
"a function over anything with these fields": nominal embedding, not row polymorphism.
- `core/encoding/json/` — what `vendor/json` is written against. Three facts were read out of it
rather than recalled. `tokenizer.odin` allocates nothing and hands back the raw literal including
its quotes, while `parser.odin:320` `unquote_string` does the copy against an allocator — which is
the split `vendor/json` copies, and the reason its `string-of` is the only function in the package
that allocates. `parser.odin:388` clones even when the literal holds no escape at all, and
`types.odin:96` `destroy_value` frees every `String` it walks — together those settle that a
`Value` owns its strings unconditionally, which is what lets one `free-all` take a whole document.
And `types.odin:49` sets `DEFAULT_SPECIFICATION` to JSON5, not JSON: `vendor/json` deliberately
does not follow that one, and every refusal in it that names a dialect names this difference.
Two Odin facts worth keeping together, because conflating them has already caused one wrong note:
**`$T` procs are monomorphised, containers are type-erased.** Odin uses both and picks per case.
### Also present, same family
`odin-examples`, `ols` (the Odin language server), `odin-imgui`,
`odin-raylib-hot-reload-game-template` — the last is a worked hot-reload loop in the language this
one borrows its memory model from.
## Lisp, conditions, and the editor loop
| Clone | Last commit | What it answers |
|---|---|---|
| `farolero` | 2023-05-05 | Common Lisp conditions and restarts, portably — a smaller read than SBCL's for *semantics*. |
| `lem` | 2025-08-29 | An editor written in CL. Its own REPL and process model. |
| `cider` | 2026-09-10 | The Clojure editor protocol this repo's `flan.el` is shaped after. |
| `emacs` | 2026-04-18 | Overlays, faces, `pre-command-hook` — the C and Lisp behind the editor half. |
| `fennel-ls` | 2026-05-06 | A Lisp language server. |
| `Carp` | 2026-08-24 | A statically typed Lisp with no GC. **The closest thing to this language's premise.** |
| `lisp` | — | assorted. |
| `cl-missile-command`, `b12n-raylib-clj`, `raylib-clojure-playground` | — | games in the Lisps, the same corpus `~/Development/fnm` ports. |
`Carp` deserves the note it has: statically typed, no GC, Lisp syntax, borrow-checked. Whatever it
got right or wrong is the nearest prior art to what is being built here.
## Compiling to JavaScript
Cloned 2026-09-17, for the JS backend (TODO.org, "A JS backend is a dialect, not a second machine").
| Clone | What it answers |
|---|---|
| `Fable` | **The best semantic match**: statically typed F# to readable JS, value-semantics structs, real i64/u64. `src/fable-library-ts/Long.ts`, `Int32.ts`, `BigInt.ts` for how .NET integer semantics live on JS numbers; `src/Fable.Transforms/` for how a typed AST lowers, including where structs get cloned at assignment and call sites. Large — read it for specific answers, not through. |
| `squint` | A small Clojure-syntax-to-JS compiler. `src/squint/compiler.cljc` is the emitter to read for output style and structure. |
| `clojurescript` | The full-size version of the same problem, including host interop. Consult, don't read through. |
The Lisp-to-JS pair never faces the two hard questions here — integer width and struct copy
semantics — because they are dynamic. Fable does, which is why it is on this list despite being
neither a Lisp nor small.
## Graphics and the C boundary
`raylib`, `raygui`, `glfw`, `SDL`, `freetype-gl`, `TIC-80`, `aseprite`, `macroquad`, `godot`, `bevy`.
`glfw` and `SDL` matter for the window and input layer raylib sits on. `TIC-80` and `aseprite` are
real C/C++ programs to read for how they structure a frame loop.
## Tooling, debuggers, terminals
`tree-sitter` (grammars — relevant if the editor mode ever stops being regexp-based), `dape` (a
debug-adapter client for Emacs), `gf` (a GDB frontend), `kitty`, `st`, `ratatui`, `stumpwm`.
`dape` and `gf` are the two to read when the debugger question comes back: this repo emits DWARF
already and `flan dev --debug` exists.
## Everything else
`Ambient`, `CelesteClone`, `RI-DASH`, `RichTextFX`, `controlsfx`, `openglfx`, `cljfx`, `pyimgui`,
`emsdk` (the Emscripten SDK — the web target uses it), `esp-idf`, `linux`, `fedora-kernel`,
`quickemu`, `OSX-KVM`, `tauri`, `keyd`, `alttab`, `xdg-ninja`, `jpm`, `cl-git`, `bragi`, `calm`,
`pretty`, `dash-*`, `graph-rag`, `gptel`, `neocaml`, `marian`, `brainfuck`,
`minimal_blockchain_in_rust`, `mpgameserver`, `computer_enhance`, `interactive-c-demo`,
`falconerd-editor`, `unity-paper.io-2`, `vscode-defold`, `PyPaperBot`, `RyzenAdj`, `Tug`,
`doom-themes`, `odin-webgl-experiment`.
`emsdk` is the only one of these on a build path — the `--target=web` build needs it.
## Related, not under `~/Repositories`
`~/Development/fnm` — the author's own falling-sand and siam-farmer ports in Clojure, Common Lisp,
jank, Janet, Odin, OCaml and JS. `PORTING.md` in this repository is the report written from reading
them, and `sand.flan` is kept at parity with `lisp/sand.lisp`, `clojure/src/fnm/sand.clj` and
`src/fnm/sand.jank`.