flan/test/programs/reload-generic.flan
Joseph Ferano b438a71031 C-c C-c on a generic installs its copies, and a refusal about one says where it came from
A generic defn produces no Tast.fn, so the editor was told nothing had
been installed and nothing had gone wrong. eval now expands a redefined
generic name to its copies, and picks up any copy the running process
was never built with - which is how a redefined caller reaching a
generic at a new element type gets that copy built and loaded.

C-x C-e is the path that could really go stale, and did: it checks
against the live environment, so an expression naming a generic at an
unused type generated a copy that existed in no program and the thunk
called a symbol nothing defined. Marked and spliced.

There was no cache to invalidate. program_with_env builds a fresh env
every evaluation, so the instantiation cache cannot survive one; the
test pins that rather than inventing machinery for it.

A signature change reaches the session as a refusal about put!-i32, a
name the source does not contain. It now says which generic it is a
copy of, at which types, and that every copy changed together.
2026-09-13 14:37:55 +07:00

40 lines
1.2 KiB
Plaintext

;;;; The session's fixture for generics in the dev loop.
;;;;
;;;; A generic [defn] never reaches [Tast.fns] — only its copies do — so every
;;;; question the editor asks about one has to be answered by expanding the
;;;; name. This file is the smallest program that makes each of those
;;;; questions concrete: one generic used at two element types, one generic
;;;; that calls another so that instantiation has to be transitive, and one
;;;; call site whose element type is *not* used anywhere else, so that a
;;;; redefinition can reach a copy the process was never built with.
(defvar counter i64)
(defn put! [xs [$t] i i32 v $t] ()
{:where (copyable? $t)}
(set (at xs i) v))
;;; Calls [put!] at its own variable, so the copy of [put!] is generated when
;;; [hold!] is instantiated and not before.
(defn hold! [xs [$t] v $t] ()
{:where (copyable? $t)}
(put! xs 0 v))
(defn pick [xs [$t]] $t
{:where (ordered? $t)}
(let [m (at xs 0)]
(dotimes [i (len xs)]
(set m (min m (at xs i))))
m))
(defn step [] ()
(let [ns [5 3 9 1]
fs [2.5 0.5 1.5]]
(hold! (slice ns 0 4) 7)
(hold! (slice fs 0 3) 0.25)
(set counter (+ counter (i64 (pick (slice ns 0 4)))))))
(defn main [] ()
(step)
(println counter))