Load.program takes forms: it reads the import forms, resolves them with the one resolver it always had, and parses the file with the packages' macros in front of it. The refusal said this needed a second import resolver at the Form level. It did not notice that the file being compiled is parsed before Load runs too, so no shape of the feature could have left import resolution where it was. Names arrive qualified, as a defn's do. (mac/twice 4) is a call and (twice 4) is an unknown name. Stopped mid-task: dune test was never run and the acceptance wiring is unfinished. HANDOFF-macros.md has what is left.
77 lines
4.2 KiB
Markdown
77 lines
4.2 KiB
Markdown
# Handoff: macros in an imported package
|
|
|
|
**Stopped mid-task when the session ended.** The feature works; the acceptance wiring is unfinished.
|
|
Its author's last words were "Works. Now the acceptance wiring." This file was written by the
|
|
coordinator from the diff and from running the program, not by the lane, so treat the "what remains"
|
|
list as read off the tree rather than as the author's own account.
|
|
|
|
## State
|
|
|
|
`dune build` succeeds. `test/programs/pkg-macro.flan` runs and prints `8 12 10 12 10 8 70 60`,
|
|
which is a package macro, a package macro that quasiquotes another, and a program macro, all
|
|
coexisting. **`dune test` was never run.** That is the first thing to do.
|
|
|
|
## The shape picked, and why the refusal's reasoning was wrong
|
|
|
|
The old refusal in `lib/load.ml` said collecting a package's macros would need that package's
|
|
imports resolved **at the Form level, before `Load` runs** — a second import resolver — and refused
|
|
rather than build one.
|
|
|
|
The lane found the premise false, and this is the finding worth keeping:
|
|
|
|
> the *file being compiled* is parsed before `Load` runs too, so no shape of the feature could have
|
|
> left import resolution where it was.
|
|
|
|
So the phases moved instead of being duplicated. **`Load.program` takes forms now**: it reads the
|
|
import forms, resolves them with the one resolver it always had, and parses the file with the
|
|
packages' macros already in front of it. There is no second resolver.
|
|
|
|
The acyclic-import guarantee is what makes this sound, and it was already there for this reason —
|
|
`load.ml`'s own comment says a definite package order is what the macro expander needs.
|
|
|
|
## The rule
|
|
|
|
Package macros arrive **qualified**, exactly as a `defn` does. A program importing the directory as
|
|
`mac` writes `(mac/twice 4)`; `(twice 4)` is an unknown name. Nothing becomes globally visible by
|
|
importing a package. Inside the package the names are unqualified, which is the rule every other
|
|
declaration there follows.
|
|
|
|
## Files touched
|
|
|
|
`bin/main.ml`, `lib/load.ml`, `lib/macro.ml`, `lib/parse.ml`, `lib/session.ml`,
|
|
`test/programs/pkg-macro.flan`, `test/programs/pkgs/mac/mac.flan`, `test/test_acceptance.ml`,
|
|
`test/test_reload.ml`, `test/test_sanitize.ml`, `test/test_session.ml`, `test/test_valgrind.ml`,
|
|
`test/test_web.ml`. 447 insertions, 117 deletions.
|
|
|
|
The test files are mostly signature churn from `Load.program` taking forms — that call is made in
|
|
many places and each had to move.
|
|
|
|
## What remains
|
|
|
|
1. **Run `dune test --root .` and make it green.** Nothing has run it. `Load.program`'s signature
|
|
changed and it is called from most test binaries, so expect breakage that is mechanical rather
|
|
than deep.
|
|
2. **Finish the acceptance wiring.** `test_acceptance.ml:1423-1427` was the refusal case
|
|
(`refuses "a macro in an imported package"`). The diff touches it; confirm it now asserts the
|
|
working program and that a *sibling* refusal pins the qualified-name rule — that `(twice 4)`
|
|
unqualified is an unknown name. `pkg-macro.flan`'s header says that refusal exists; verify it
|
|
does.
|
|
3. **Check the non-termination refusals still fire** when the macros come from a package: a ring of
|
|
macros is named, a macro that does not settle is bounded. `BUILT.md` records both. Neither was
|
|
confirmed under the new path.
|
|
4. **Check the dev loop.** A macro imported by the file being edited must still be available on a
|
|
`C-c C-c`. `lib/session.ml` is in the diff, so this was at least considered, but nothing proves
|
|
it. `test/test_session.ml` and `test/test_dev.ml` show how sessions are driven.
|
|
5. **Measure the build cost** against the recorded baseline in `BUILT.md`: 50ms for a build naming
|
|
no macro, 310ms cold and 70ms warm for one calling a macro. Whether reading a package's forms
|
|
earlier moved those numbers is unknown.
|
|
6. **`vendor/raylib` is the customer.** `with-drawing` and `with-mode-2d` over raylib's
|
|
`BeginDrawing`/`EndDrawing` and `BeginMode2D`/`EndMode2D`, so an unbalanced pair stops being
|
|
possible. A raylib lane tried and could not; that is what prompted this work. Not started here
|
|
and deliberately out of scope — that file was held by another lane at the time.
|
|
|
|
## Not verified
|
|
|
|
Everything above item 1. The program runs and the build is clean; that is the whole of what is
|
|
known to work.
|