Three roles want three words, and two of them want the same dependency tracking
This commit is contained in:
parent
f1223cde2e
commit
a8a032e340
41
DISCUSS.md
41
DISCUSS.md
@ -68,18 +68,41 @@ function behind an indirection cell, or a constant by its source name, needs no
|
||||
information the daemon already has. Writing a disassembler is not the interesting part and should stay off the table;
|
||||
richer annotation of objdump's output is cheap and is where SBCL's advantage actually comes from.
|
||||
|
||||
## 3. `def`, `defvar`, `defconst`
|
||||
## 3. `def`, `defvar`, `defconst` — three roles, currently two words
|
||||
|
||||
There is no `def`. There is `defvar` (mutable global) and `defconst` (compile-time constant, folded).
|
||||
There is no `def`. `defvar` is a mutable global that is always re-initialised on redefinition; `defconst` is a
|
||||
compile-time constant, folded into its use sites.
|
||||
|
||||
The proposal: a `def` that is mutable, where `defvar` only rewrites the value if the variable is *new* — Common Lisp's
|
||||
actual `defvar` semantics, where re-evaluating a `defvar` deliberately does not clobber a value you have been building up
|
||||
at runtime. That distinction matters much more here than in most languages, because `C-c C-k` on a whole buffer
|
||||
re-evaluates every top-level form against a *running* program, and today that resets state you may have spent a session
|
||||
accumulating.
|
||||
The problem in practice: `C-c C-k` re-evaluates every top-level form against a *running* program, so today it wipes
|
||||
state you may have spent a session accumulating.
|
||||
|
||||
`defconst` under redefinition is the unclear one, as noted — it is folded into its use sites, so changing one is closer to
|
||||
a recompile than to an assignment.
|
||||
**Settled in conversation — three roles, three words:**
|
||||
|
||||
- **`def`** — always re-initialised. The tweakable: some number you are adjusting and do not care about preserving.
|
||||
- **`defvar`** — re-initialised *only if it would come out different*. For heavier initialisers: an N×M grid that should
|
||||
recompute only when the rows or columns actually changed.
|
||||
- **`defconst`** — folded, and reserved for what genuinely cannot change for the life of the program. `rows`/`cols` in
|
||||
`sand.flan` are honest `defconst`s: the program does not support resizing on the fly and changing them means resetting
|
||||
everything anyway.
|
||||
|
||||
Note this **`defvar` is not Common Lisp's**, which is "assign only if unbound". This one is value-dependent, which suits
|
||||
a live-edited game better and is the harder of the two to implement.
|
||||
|
||||
**The open question is what "different" means**, and the grid example is what makes it sharp. If the grid is sized by
|
||||
`rows` and `cols`, the initialising expression's *text* is unchanged when `rows` changes — only its value is. So:
|
||||
|
||||
1. **Compare the expression** (textual or AST). Cheap, and does not catch the case above.
|
||||
2. **Compare the expression plus everything it depends on.** Catches it. Needs dependency tracking.
|
||||
3. **Evaluate and compare the result.** Correct, and defeats the entire purpose whenever the initialiser is expensive —
|
||||
which is the only case this feature exists for.
|
||||
|
||||
Option 2 is what is wanted.
|
||||
|
||||
**The reason to do it: it is the same machinery `defconst` needs.** A folded constant cannot be tuned live, because its
|
||||
value is baked into every function that used it — so the values you most want to tweak while the game runs are exactly
|
||||
the ones you cannot. Fixing that means knowing which functions depend on which constants, and rebuilding those. That is
|
||||
the same dependency tracking `defvar`'s "if different" requires. Built once, it buys live-tunable constants *and* the
|
||||
conditional re-initialisation. Neither is worth building alone; together they are clearly worth it.
|
||||
|
||||
## 4. Structural typing, row polymorphism, anonymous structs
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user