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.
54 lines
1.9 KiB
Plaintext
54 lines
1.9 KiB
Plaintext
;;;; Three edges of Reach's walk, each the only route to one function.
|
|
;;;;
|
|
;;;; A release build is pruned: a function nothing reachable from main or from
|
|
;;;; a global initialiser calls is not emitted at all. So an edge the walk
|
|
;;;; forgets does not produce a wrong answer — it produces a program that does
|
|
;;;; not link, with a message about a symbol nobody wrote. Each of the three
|
|
;;;; functions below is called from exactly one place, and that place is an
|
|
;;;; edge no other program in the corpus exercises:
|
|
;;;;
|
|
;;;; index-expr the index expression of a place, (set (at a (f)) v)
|
|
;;;; through a place under (addr ...), here a (deref ...) so that it is
|
|
;;;; the addr edge and not the index one again
|
|
;;;; placeholder a restart-case clause body, which is reached by a transfer
|
|
;;;; and never by a call the walk can see from the body
|
|
;;;;
|
|
;;;; Nothing here is about the values; the values are how the test notices that
|
|
;;;; the program was built and ran at all.
|
|
|
|
(defonce cells [4 i32])
|
|
(defonce slot i32)
|
|
|
|
(defstruct Nope [id i32])
|
|
|
|
(defn index-expr [] i32 2)
|
|
|
|
(defn through [] (Ptr i32) (addr slot))
|
|
|
|
(defn placeholder [] i32 42)
|
|
|
|
;;; Signals with nothing to return, so the clause body is the only way past.
|
|
(defn missing [] i32
|
|
(error (Nope {.id 1})))
|
|
|
|
(defn pick [] i32
|
|
(restart-case (missing)
|
|
(use-placeholder [] (placeholder))))
|
|
|
|
(defn main [] i32
|
|
;; The index of a place is an expression, and it can call.
|
|
(set (at cells (index-expr)) 10)
|
|
(print (at cells 2)) (println "")
|
|
|
|
;; (addr (deref p)) is p, so this is the addr edge over a place whose own
|
|
;; walk is Pderef rather than Pindex — the index case above cannot stand in
|
|
;; for it.
|
|
(let [q (addr (deref (through)))]
|
|
(set (deref q) 20))
|
|
(print slot) (println "")
|
|
|
|
;; The clause body, reached only because the handler transfers into it.
|
|
(handler-bind [(Nope [c] (invoke-restart 'use-placeholder))]
|
|
(print (pick)) (println ""))
|
|
0)
|