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.
40 lines
1.2 KiB
Plaintext
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))
|