diff --git a/FIX.org b/FIX.org index 9c083d1..f0e0401 100644 --- a/FIX.org +++ b/FIX.org @@ -24,3 +24,103 @@ If game-data.edn genuinely must be loaded at runtime, then today it has to be ow ** defenum needs optional autoincrementing discriminants ** We need a javascript backend so we can reach the world ** We need to have C-style unions, maybe those are called defunion, and then sum types are defdata or deftype + +* Decisions, 2026-09-17 + +** 1. Re-runnable main — DISPATCHED +The process does not actually die. [flan_exit_hook] is [flan_merged_exit] +(lib/dev.ml:2669): it flushes, reclaims fd 1, and parks in [for (;;) pause()]. +What is missing is a way to wake it. The park becomes a condvar wait, a daemon +op signals it, and the main thread — not a new one, because raylib wants the +main thread — re-enters [flan_program_main]. [alive] gains a third state, +parked-and-re-runnable, and each of the ten guard sites decides for itself +whether it accepts one. + +Globals are NOT reset between runs. That is the CL/Clojure semantics asked for: +the process never died, so a second (main) sees what the first one left. + +** 2. C-x C-e on a top-level form — QUEUED behind 1 +Same file as 1 (emacs/flan-dev.el), so it waits rather than merging by hand. +No design questions; the note specifies it. + +** 3. Runtime-loaded owning globals — DISPATCHED +Not a missing global ownership model. One rule: a move-only global is legal, +and reading one is always a borrow, never a move. Nothing takes ownership, +nothing frees it, its lifetime is the process's. Sound precisely because the +lifetime question has a constant answer. + +Mutable in place as well — a global Vec can be pushed to. Aliasing follows +whatever locals already do; no new borrow regime for globals that locals lack. + +[embed] (lib/check.ml:4265) still covers build-time data and is untouched. + +** 4. edn both typed and dynamic — QUEUED behind 3 +Two projects, not one. (read-edn T bytes) does not exist — vendor/edn/edn.flan +is only a tokenizer, and the compile-time struct walk is NEXT.md item 9. + +The dynamic half is blocked: a dynamic EDN value is recursive, so it is a Vec +whose element is move-only, which lib/check.ml:599 refuses and whose refusal +names [drop] as the fix. So [drop] gets unstashed — it now has the customer +NEXT.md:225 said it lacked. Full spec-memory.md:338 scope: recursive teardown +AND the hook. Queued behind 3 because both land in check.ml. + +** 5. defenum autoincrement — DISPATCHED +C's rule: no value means previous+1, the first is 0, explicit and implicit mix. + +Duplicates: an explicitly written one is an intended alias and is allowed. One +produced by autoincrement walking into a value another member holds is an +accident and is refused, naming both members. + +** 6. JavaScript backend — HELD +wasm32 already works: test/wasm-run.mjs is a WASI host, the test table runs +wasm32 builds, web/index.html is in the tree. A second backend beside emit.ml +and x86.ml is the largest item here and the dev loop comes first. + +** 7. defdata and defunion — QUEUED last +Today's [defunion] is already the tagged sum type. It is renamed [defdata], +and [defunion] becomes the C-style untagged one. Serves both FFI and type +punning, and cimport verifies it against the header where one exists — +cimport.ml:295 currently skips any record holding an anonymous union, leaving +the defstruct beside it unchecked. + +Last, because the rename sweeps parse/check/emit/prelude/docs and every .flan +file, and would conflict with everything above. + +* Open, found while working the list + +** A transient signal -11 on the globals daemon +Seen once, in one of three consecutive test runs, by the agent doing the +C-x C-e work; the runs either side of it were clean. Not reproduced since — +three forced full runs (dune test --force) are green, 232 checks, 0 failures. + +Worth remembering rather than chasing, because the daemon it appeared on is +one the move-only-global work (c124df3) changed: test_reload's fixture gained +a host global Vec and a run-time-new one. A teardown or a reload module that +defines rather than declares a global Vec would strand the block the live +process is using, which is exactly the shape a rare SIGSEGV takes. If it comes +back, start there. + +* Landed on dev-loop + +Items 1, 2, 3 and 5 are merged and green (dune test --force, 232 elisp checks, +0 failures). Items 4 (drop) and 7 (defdata) are still being written. Item 6 is +held. + +** Re-run is merged, and does not work under --x86 +Park and re-run live in the merged entry point's main(), and --x86 refuses the +merged daemon by design: a merged host exports every flan.* body for -rdynamic +and so interposes the prelude bodies of the LLVM-built macro module the +compiler loads into itself. --x86 therefore runs --two-process, where the +program is a child, and a child that finishes is genuinely Gone — there is +nothing to wake. [Program.rerun] answers with the two-process refusal rather +than the merged one, and a test pins it. + +Re-run on x86 needs the merged daemon to accept --x86 first. Separate work. + +** The headline complaint is verified fixed on sand.flan +Window opened, closed, the daemon reported parked, (:op "rerun") returned ok, +and xdotool found a live window from the second run. + +The earlier claim that [flan dev sand.flan] failed with "unknown function +begin-drawing" was true only on the stale base the work started from, and was +retracted after a re-test. Nothing to chase.