The trio the author decided on 2026-09-20 is now all built: def is CL's defparameter — its initialiser runs on every daemon re-run, unguarded, so an edited initialiser repaints the same storage on C-c C-c plus re-run — defonce (Clojure's name for CL's defvar, per the author) initialises once behind the .init~once. flag, and defconst stays the image. One parse arm reads both forms; the difference is Ast.reinit, carried to Tast.global's grerun. Emit.startup_plan gives a def no guard flag, and Check.check_global lifts every def initialiser — zero and literal included — into global/<n>, so the host's startup reaches it through the function cell and a re-evaluated def swaps it (Session's def_inits; Emit.redefinition declares the cell for a non-sibling target). The old defvar spelling is refused with the rename and both compiling spellings, and every program, test, doc and editor list is swept — except sand.flan, the author's live WIP, whose seven defvar lines are flagged in FIX.org and keep its three dependent tests red on this branch.
44 lines
1.8 KiB
Plaintext
44 lines
1.8 KiB
Plaintext
;;;; dev-loop.flan's shape, with a macro in it, and the macro is the whole
|
|
;;;; point of the file.
|
|
;;;;
|
|
;;;; [flan dev]'s merged daemon is the program and the compiler in one process,
|
|
;;;; and the compiler expands a macro by dlopening a module into *itself* --
|
|
;;;; which is now also the program's address space. The module is always built
|
|
;;;; by LLVM whatever backend the session uses, and the host is linked
|
|
;;;; -rdynamic so a redefinition module can reach its cells, so until
|
|
;;;; Build.macro_module hid the module's own Flan definitions the host's bodies
|
|
;;;; interposed them. Under --x86 that is a crossed pair and it was a SIGSEGV
|
|
;;;; during the first expansion, before the program had run a line.
|
|
;;;;
|
|
;;;; So [unless] is called twice over: once here at the top level, which is the
|
|
;;;; expansion that used to kill the daemon on its way up, and once from a body
|
|
;;;; typed in later, which is the same expansion with the program already
|
|
;;;; running beside it.
|
|
(import agent "vendor:agent")
|
|
|
|
(defonce ticks i64)
|
|
|
|
(defn parity [n i64] string
|
|
(let [out "even"]
|
|
(unless (= 0 (% n 2))
|
|
(set out "odd"))
|
|
out))
|
|
|
|
(defn step [] i64
|
|
(set ticks (+ ticks 1))
|
|
ticks)
|
|
|
|
;;; A *bounded* run of frame boundaries, where dev-loop.flan waits for a
|
|
;;; delivery and dev-repl.flan runs long enough to outlast a whole test file.
|
|
;;; This program is here to park, and it has to park whether or not the thing
|
|
;;; that was delivered to it is one [agent/wait] reports — so the clock ends
|
|
;;; it rather than the editor does. Two seconds is long enough for a client to
|
|
;;; be served twice and short enough to be well inside a watchdog.
|
|
(defn main [] i32
|
|
(agent/start "/tmp/flan-dev-macro-fallback.sock")
|
|
(println (parity (step)))
|
|
(dotimes [i 400]
|
|
(agent/wait 5))
|
|
(println (parity (step)))
|
|
0)
|