res-sheets: calc multi-pass convergence (fix wrong exports) #2
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
residual/.agent#2
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Plan:
res-sheets calcmulti-pass convergenceProblem (confirmed)
The oneshot
calcpath callssh.Recalc()exactly once (extra/cmd/res-sheets/calc.go:46). A single pass is insufficient forcell.thisself-referential lua cells, which read their own previous-passLivingvalue viaLastGood(recalc.go:31-36,lua_eval.go:160-162).TestLuaCellThisproves such a cell only reaches its correct value on the secondRecalc()— first pass has emptyLastGood, so(cell.this or 0)+1yields1instead of2. Oneshot calc emits only the first (wrong) pass, so critical script cells export empty/wrong values.Not affected: true graph cycles are marked
#CIRCU!by Kahn's algorithm every pass and never get a value. Volatile functions already render in a single pass.Goal
Run
Recalc()N times in the calc path and emit the final pass, socell.thisself-referential cells converge. True cycles keep#CIRCU!. Non-determinism acceptable.Decisions (from user)
--passes=Nflag.#CIRCU!(onlycell.thislua cells converge).Changes
extra/cmd/res-sheets/calc.go— addflag.FlagSetwith-passes(default20; constdefaultCalcPasses); replace singlesh.Recalc()withfor i := 0; i < passes; i++ { sh.Recalc() }; update usage string.extra/lib/sheets/recalc.go— no signature change; optional doc comment noting safe to call repeatedly for convergence.docs/extra/extra.md(ordocs/extra/sheets-functions.md): documentres-sheets calc <input> [output] [--passes=N]; explain multi-pass lets self-referential/volatile-dependent cells settle; note cyclic cells still emit#CIRCU!.extra/lib/sheets/lua_test.goorrecalc_test.go:TestRecalcMultiPassConverges(sheet with=lua{(cell.this or 0)+1}; assert afterRecalc()×N (N≥2) value equalsN).extra/cmd/res-sheets/calc_test.go: fixture withcell.thislua cell; runrunCalcwith-passes=5; assert exported*.sheet-out.csvcontains5, not1.Affected repos
extra/only. No change tocore/,docs/,os/,editor/. (store.LoadWorkbook's singleRecalc()atstore.go:249intentionally unchanged — serves interactive/TUI load, not oneshot export.)Risks
Verification
Manual smoke:
Open question (non-blocking)
Default pass count of 20 is a guess at the "10+10" model. Want a different default? Flag overrides regardless.
Worth-it verdict
Yes — small, contained fix (one loop + flag + tests + docs) correcting a real silent-correctness bug in exported output.