flan/test/programs/shadow-builtin.flan
Joseph Ferano a4c6b996ff def re-runs its initialiser, and defvar is renamed defonce
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.
2026-09-21 07:12:04 +07:00

46 lines
2.1 KiB
Plaintext

;;;; A defn named after a builtin, and what the name means afterwards.
;;;;
;;;; "Allow shadowing but warn": this file's (defn get ...) is legal, it wins
;;;; at every call site in this file, and the compiler says so once at the
;;;; definition — the warning is on stderr and the exit status does not move.
;;;;
;;;; Five lines printed, and between them the whole rule. In order:
;;;;
;;;; - 7: (get p) is one argument, which the builtin get does not take. It
;;;; compiles, and it prints the field, because the name resolves to the
;;;; definition below and the builtin is not consulted about its arity.
;;;; - 4: (shadowed/field m) reaches into the imported package, whose body
;;;; calls the builtin get on a dyn map. The shadow does not follow it
;;;; there: a package's calls mean what they meant when it was written.
;;;; - 99: an operator is a builtin like any other and shadows like one.
;;;; - 999: this file's own len, which is what len means in this file.
;;;; - 4 again, and it is the one that needed the work: the package's global
;;;; initialiser (defonce size i32 (len "abcd")) is checked with no
;;;; enclosing function at all, so there is no qualified name on it to say
;;;; it belongs to a package. The file it was written in says so instead.
(import shadowed "pkgs/shadowed")
(defstruct P [x i32])
(defn get [p P] i32 (.x p))
;;; An operator is a builtin like any other, and shadows like any other: (+ 1
;;; 2) below is this definition and answers 99. Nothing else in the program
;;; adds anything, and the prelude's own additions are untouched — the
;;; prelude is a different file.
(defn + [a i32 b i32] i32 99)
;;; And a builtin the imported package uses in a *global initialiser*, which
;;; is the one place there is no enclosing function to carry a package's
;;; qualified name. The package's (defonce size i32 (len "abcd")) is 4; this
;;; definition answers 999 and is reached only here.
(defn len [s string] i32 999)
(defn main [] ()
(println (get (P {.x 7})))
(println (shadowed/field {:a 1 :b 4}))
(println (+ 1 2))
(println (len "abcd"))
(println (shadowed/stored-size)))