Three escape tables became two, and the docs catch up
SPIKE-DUPLICITY.md 9 and SPIKE-DYNAMIC.md both still counted three and quoted a flan_dyn.c comment that has since been rewritten. The typed side two are one flan_escape_char with a framing each; the dyn copy stays, with the ownership defence the section already accepted. NEXT.md named flan_break_resume, which does not exist -- flan_restart_frame and flan_restart_take are the pair a break loop resumes through.
This commit is contained in:
parent
6461322aa9
commit
2d29528cad
7
NEXT.md
7
NEXT.md
@ -2395,8 +2395,11 @@ plan.org's single line on it (831) names a `for` the language does not have and
|
||||
What is missing is the half only an editor can do — the leverage SBCL lacks. `eval` already compiles and runs an
|
||||
expression inside the live program and the daemon already holds the struct layouts, so "ask the human, type-check
|
||||
the answer, hand it over" is a short hop, and it is the one path the runtime today *refuses*: a restart with
|
||||
parameters taken from the break loop traps, because `flan_break_resume` and `flan_restart_take` aim the channel at
|
||||
a frame and have nothing to fill its buffer with. What it needs, end to end:
|
||||
parameters taken from the break loop traps, because the pair a break loop resumes through — `flan_restart_frame`,
|
||||
which hands back the frame the human picked, and `flan_restart_take`, which aims the transfer channel at it —
|
||||
reaches the frame and has nothing to fill its buffer with. (`flan_break_resume` is what this paragraph named
|
||||
before; there is no such function, and `flan_break_hook` is the unrelated thing that gets the break loop *into*
|
||||
the agent in the first place.) What it needs, end to end:
|
||||
- the frame already carries the arity and the signature as a string — `flan_restart_arity` and `flan_restart_sig`
|
||||
beside `flan_restart_name`, the same walk, so `restarts` can say what each one takes;
|
||||
- `:restarts` on the wire carries the signature per entry, so the minibuffer can show `use-value (i32)` rather
|
||||
|
||||
@ -425,23 +425,28 @@ and reload semantics are working." Under this reading the gating item changed. C
|
||||
|
||||
## 9. Print, hash, sort — one family already duplicated, two not yet
|
||||
|
||||
**Printing is duplicated three ways on one side, and it is not the dyn/typed split.**
|
||||
`runtime/flan_dyn.c:308-313` says so itself:
|
||||
**Printing was duplicated three ways on one side, and it is not the dyn/typed split. Two of the three are
|
||||
now one.** This section found three escape tables; the runtime dedupe lane took the two that were on the
|
||||
same side and made them one function with two framings, which is what this section asked for. What is left
|
||||
is the split it argued was correct.
|
||||
|
||||
> A text inside a structure, quoted and escaped. The same table as `flan_rt.c`'s `flan_escape_bytes` and
|
||||
> `flan_dev.c`'s `flan_dev_emit_str`...
|
||||
The table lives once, as `flan_escape_char` (`runtime/flan_rt.c:388`), and both typed-side printers call
|
||||
it: `flan_escape_bytes` (`:422`), which builds a capped slice for `println`, and `put_str`
|
||||
(`runtime/flan_dev.c:302`), which streams into the inspector's fixed buffer so the REPL can parse the
|
||||
printed form back. The framing is each caller's and is the part that is genuinely theirs; the switch is
|
||||
shared, because two printers disagreeing about what a string looks like is two wire formats.
|
||||
|
||||
Three escape tables: `runtime/flan_rt.c:383` (`flan_escape_bytes`, with `:366-372` noting it is already "the
|
||||
same escape table as `flan_dev_emit_str`"), `runtime/flan_dev.c:237` and again at `:551`, and
|
||||
`runtime/flan_dyn.c:314` (`emit_escaped`). `SPIKE-DYNAMIC.md:329-332` calls its own "the third copy" and
|
||||
leaves the instruction "If that table changes, change all three."
|
||||
The dyn copy stays, as `emit_escaped` (`runtime/flan_dyn.c:472`), and says why at `:465-470`:
|
||||
|
||||
Two of those three are on the same side. `flan_rt.c`'s is `println`'s; `flan_dev.c`'s is the inspector's, so
|
||||
the REPL can parse the printed form back. That pair predates dyn and is same-side duplication that dyn has
|
||||
now made three-way. The *dyn* copy is the one with a defence, and `SPIKE-DYNAMIC.md:334-338` gives it: a
|
||||
typed `Vec` prints as `<vec>` because the typed printer will not walk storage it does not own, while a dyn
|
||||
vec's storage belongs to the collector and the printer is inside the runtime that owns it. That is correct
|
||||
duplicity. Three tables is not.
|
||||
> This copy is deliberate, and the argument for it is docs/SPIKE-DUPLICITY.md §9's: the dyn printer lives
|
||||
> inside the runtime that owns the storage it walks, which is why it prints a dyn vec structurally where
|
||||
> the typed printer answers `<vec>`. The whole printer is this side's; the table it shares with the other
|
||||
> side is the part that must not drift. If that table changes, change this one.
|
||||
|
||||
That is the defence `SPIKE-DYNAMIC.md` gives and this section accepted: a typed `Vec` prints as `<vec>`
|
||||
because the typed printer will not walk storage it does not own, while a dyn vec's storage belongs to the
|
||||
collector and the printer is inside the runtime that owns it. One copy per *side*, which is the doctrine.
|
||||
Two tables is the answer; three was not.
|
||||
|
||||
**Hashing is typed-only.** `flan_hash_fn`, `flan_hash_flat`, `flan_hash_str`, `flan_hash_combine`
|
||||
(`runtime/flan_rt.c:1807, 1911, 1939, 1954`), reached through `Types.keyable` and the checker's `key_pair`
|
||||
|
||||
@ -326,10 +326,12 @@ running program**, not read off `lib/render.ml` — that file is the REPL's insp
|
||||
| nil | — | `nil` |
|
||||
|
||||
The leading space before every element is what `lib/render.ml`'s slice loop emits and what a Flan program
|
||||
prints today; a tidier answer would diverge from an acceptance test. The escape table is the third copy
|
||||
of the one in `flan_rt.c`'s `flan_escape_bytes` and `flan_dev.c`'s `flan_dev_emit_str` — those two are
|
||||
already kept identical because the REPL parses the printed form back, and this one joins them. If that
|
||||
table changes, change all three.
|
||||
prints today; a tidier answer would diverge from an acceptance test. The escape table is the dyn side's
|
||||
own copy of the typed side's. The typed side used to have two and now has one — `flan_escape_char`
|
||||
(`runtime/flan_rt.c:388`), which `flan_escape_bytes` calls for `println` and `flan_dev.c`'s `put_str`
|
||||
calls for the inspector, each framing the result its own way — so there are two tables in the tree, not
|
||||
three, and the split that is left is the dyn/typed one argued just below. If that table changes, change
|
||||
this one too.
|
||||
|
||||
**A typed `Vec` prints as `<vec>` and a dyn vec does not.** That looks like a mismatch and is not. The
|
||||
typed printer's refusal is about walking storage it does not own — `render.ml` says so, and directs you to
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user