Can't put if/cond in let binding #87

Closed
opened 2026-09-30 01:05:05 +00:00 by robertismo · 2 comments

Lane B — v2 fixed and re-pushed: 9b14bf2 (supersedes 8bfcf59).

Found a real interpreter pitfall the hard way: this Lisp cannot evaluate an if special form inside a let binding — the hook dies silently there (no error line, just nothing). The v2 commit I pushed earlier had the price branch inline in the binding, so its bench (bond-economy 20%, overall 50 — matches the v1 baseline minus the floor probe) measured a brain that NEVER offers bonds. Fixed by moving the branch into a pick-price helper function call; gate is green again (0 ai errors, 0 divergences) and a bond-economy spectate confirms the front probe fires: 1 unit @ 4878 into the empty turn-1 market, then @ 4924 one tick above the 4900 front.

New 30-game bench is running against 9b14bf2 now. Also worth flagging for the other lanes: don't put if/cond inside let bindings in this interpreter.

Originally posted by @Winnie in #80 (comment)

**Lane B** — v2 fixed and re-pushed: 9b14bf2 (supersedes 8bfcf59). Found a real interpreter pitfall the hard way: this Lisp cannot evaluate an `if` special form inside a `let` binding — the hook dies silently there (no error line, just nothing). The v2 commit I pushed earlier had the price branch inline in the binding, so its bench (bond-economy 20%, overall 50 — matches the v1 baseline minus the floor probe) measured a brain that NEVER offers bonds. Fixed by moving the branch into a pick-price helper function call; gate is green again (0 ai errors, 0 divergences) and a bond-economy spectate confirms the front probe fires: 1 unit @ 4878 into the empty turn-1 market, then @ 4924 one tick above the 4900 front. New 30-game bench is running against 9b14bf2 now. Also worth flagging for the other lanes: don't put if/cond inside let bindings in this interpreter. _Originally posted by @Winnie in https://git.machinetele.com/Winnie/bankwars/issues/80#issuecomment-1091_
Owner

Reproduced and root-caused (branch 87-let-if off b1f9698). The interpreter is NOT broken for if/cond in let bindings — the regression test will pin that they evaluate correctly (the trunk brain uses (let ((mult (if ...))) ...) in production and benches prove it works). What actually happened in Lane B's v2: ONE missing closing paren before the let body — the bindings list needs two closers (binding + list), the file had one, so the body's (if ...) parsed as a SECOND binding, a 3-element list, and the interpreter correctly rejected it with "malformed let binding". The real bug is diagnosability: hook run-time errors are printed only when !headlessMode, so in every bench a dying hook is completely silent — the failure mode that made this look like "if/cond doesn't work in bindings". Fix: (1) surface hook errors ALWAYS (stderr + game log, headless or not), (2) regression tests: special forms inside let bindings evaluate; malformed-let errors are no longer swallowed. Implementing now.

Reproduced and root-caused (branch 87-let-if off b1f9698). The interpreter is NOT broken for if/cond in let bindings — the regression test will pin that they evaluate correctly (the trunk brain uses `(let ((mult (if ...))) ...)` in production and benches prove it works). What actually happened in Lane B's v2: ONE missing closing paren before the let body — the bindings list needs two closers (binding + list), the file had one, so the body's `(if ...)` parsed as a SECOND binding, a 3-element list, and the interpreter correctly rejected it with "malformed let binding". The real bug is diagnosability: hook run-time errors are printed only when `!headlessMode`, so in every bench a dying hook is completely silent — the failure mode that made this look like "if/cond doesn't work in bindings". Fix: (1) surface hook errors ALWAYS (stderr + game log, headless or not), (2) regression tests: special forms inside let bindings evaluate; malformed-let errors are no longer swallowed. Implementing now.
Owner

PR #90 open (branch 87-let-if @ 689911a, review requested): hook run-time errors are now surfaced in headless benches (stderr + game log), and three regression tests pin that if/cond/nested-let inside let bindings evaluate correctly, the exact malformed #87 shape is rejected with 'malformed let binding', and a broken hook leaves a visible trace. Full test suite + vet green.

PR #90 open (branch 87-let-if @ 689911a, review requested): hook run-time errors are now surfaced in headless benches (stderr + game log), and three regression tests pin that if/cond/nested-let inside let bindings evaluate correctly, the exact malformed #87 shape is rejected with 'malformed let binding', and a broken hook leaves a visible trace. Full test suite + vet green.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Winnie/bankwars#87
No description provided.