5 Commits

Author SHA1 Message Date
59e9392ec8 What the class decision changes for the next session
plan.org's managed classes arrived after NEXT.md's handoff was written, so a
session reading the plan cold would take them as the next task. They are not:
plan.org's own last line on them says nothing until struct, Handle and reload
semantics work, and that belongs where the next task is named.

Three findings from reviewing it that are not in plan.org. A generic function is
a cell whose body is a dispatch table - adding a method later is the same
problem the indirection cells already solve, so the expensive half of classes is
built. Migration has to enumerate live instances, which makes the pool behind a
generational Handle the only one of the three storage options that obviously
supports it, rather than a free choice. And a numbered layout has to stay
resolvable for migrate to dispatch on, which is the same retention rule as
nothing is ever dlclosed.

Also records the open question the class facility raises for conditions: whether
a condition may be a class, what the hierarchy would buy, and the three costs -
allocation on the signal path being the serious one. It wants answering before
handler-case, since it decides whether handler matching has one path or two.

Plus three nits in the new prose: float/int are not Flan type names, the place
syntax was dotted, and the migration example set a slot the class did not have.
The tag-word sentence said any was the only place one is paid, which Error and
now a class instance both make false.
2026-09-11 17:35:06 +07:00
ac8d31ee65 Managed classes, planned and deliberately separate from structs
The struct/class split, written down before anything is built on it. A struct
stays a fixed-layout value with C's layout, which is what keeps the FFI, SoA and
wasm stories intact; a class is a separate kind with identity, metadata and an
implementation-defined representation, for the long-lived gameplay objects that
want to change shape while the program is running.

The tagline loses "no GC" for "no mandatory GC", because a small collector
confined to class instances is now an option rather than a contradiction. CLOS
goes from a flat non-goal to a bounded one: the metaclasses, method combination
and arbitrary change-class are out; exact-class single dispatch and an explicit
frame-boundary migration are in.

Migration is eager and explicit rather than CLOS's lazy-on-access, which would
put a check on every slot read. Class identity is stable and layouts are
numbered, the same shape as the function versions the hot reload section grew.

Nothing is frozen and nothing is to be built until struct, Handle and reload
semantics are working.
2026-09-11 17:34:13 +07:00
943561e765 A map entry is not a place
spec-memory.md drops (set (get m k) v) from the assignable forms: a map has an
upsert of its own, put, which either inserts or replaces, so there is no store
into a lookup - and an absent entry has no location to store into anyway.

The compiler still parsed it into an Ast.Pkey and refused it downstream as
unimplemented, milestone 6, which is the wrong reason for something that is
never arriving. The place form is gone from ast, tast, load, check and emit,
and the parser refuses the shape where it is written, with the reason and a
pointer to put.
2026-09-11 12:23:10 +07:00
5a8c2327c6 Debugging: DAP for the machine layer, nREPL for the language layer
Do not extend nREPL with registers -- the protocol is trivial, the
implementation is a whole debugger. Emit DWARF from the LLVM backend
and use lldb-dap with dape; no adapter is written. C layout with no
object headers means DWARF describes Flan structs exactly, so lldb
needs no plugin or formatters.

Reload mostly works with DAP for free: lldb watches the loader
rendezvous and re-resolves breakpoint specs against new modules. The
gotcha is our own never-unload rule -- N redefinitions leave N copies
all claiming the same source line, so one breakpoint resolves to N
locations. Needs per-generation DWARF source identity plus a reload
agent that disables superseded locations.

Cuts the instrumentation-based step debugger, the most expensive piece
of milestone 8. Knock-on: &env stops being urgent, and the shadow stack
shrinks to serving nREPL backtraces and restart enumeration.
2026-09-10 16:04:56 +07:00
e9cdbb321b Lisp based flan 2026-09-10 14:40:34 +07:00