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.
48 lines
2.2 KiB
Plaintext
48 lines
2.2 KiB
Plaintext
;;;; The reload primitive's fixture, v1 (NEXT.md, dev loop step 1 and 2).
|
|
;;;;
|
|
;;;; There is deliberately no [main]: the host is reload_host.c, which links
|
|
;;;; this program and then dlopens two rebuilt copies of [bump].
|
|
;;;;
|
|
;;;; [counter] is the state that has to survive a reload — a redefinition
|
|
;;;; module declares it [external], so the loaded object writes the host's copy
|
|
;;;; and not a new one. [outer] is the call site that has to *follow* a reload:
|
|
;;;; it is compiled once, into the host, and never rebuilt, so if a redefined
|
|
;;;; [bump] runs when the host calls [outer] then the cell is doing its job.
|
|
;;;; The string is not decoration either — a redefinition module has to carry
|
|
;;;; its own constants, and a one-function module usually has none.
|
|
(defonce counter i64)
|
|
|
|
;;; A move-only global, which is allowed because reading one is always a borrow
|
|
;;; (spec-memory.md, "Globals of move-only type"). It is here for the reload
|
|
;;; question rather than the ownership one: a redefinition module declares it
|
|
;;; [external] like any other host global, so a load must not hand the module
|
|
;;; its own zeroed header -- that would drop the storage the running process is
|
|
;;; still using, which is the failure a plain i64 counter cannot exhibit
|
|
;;; because a re-zeroed i64 merely looks wrong.
|
|
(defonce tally (Vec u8))
|
|
|
|
;;; Unused, and that is the point: the session's compatibility rules only get a
|
|
;;; chance to speak about a change the *checker* accepts, and retyping a var
|
|
;;; something else reads is an ordinary type error long before it is a layout
|
|
;;; question.
|
|
(defonce spare i64)
|
|
|
|
;;; Also unused, and for the same reason: a defconst's value and an enum
|
|
;;; member are folded into every call site, so a session has to refuse changing
|
|
;;; either. Nothing here reads them, so the checker has no opinion and the
|
|
;;; session's rule is the only thing that can speak.
|
|
(defconst folded i64 7)
|
|
;;; ...and one that is not: an array constant is never an array length, so its
|
|
;;; value is only ever read at run time and a dev build can store a new one.
|
|
(defconst palette [2 u32] [1 2])
|
|
(defenum Colour [red 0 green 1])
|
|
|
|
(defn helper [x i64] i64 (* x 2))
|
|
|
|
(defn bump [] i64
|
|
(println "v1")
|
|
(set counter (+ counter 1))
|
|
(helper counter))
|
|
|
|
(defn outer [] i64 (bump))
|