docs: Notes for the laziness runtime contract (#44)#127
Merged
Conversation
- Note [The runtimeLazy calling convention] (Backend.Lua.Fixture): the curried name -> init -> force shape and why state/val must live in the function(init) closure (the scope error fixed in #126). Points at the two transform sites that must match the arity. - Note [Laziness transform for recursive binding groups] (CoreFn.Laziness): a citable anchor for the transform; the detailed upstream-adapted prose is left untouched (delay/force and init-order rules) to avoid divergence. - Correct two comments inherited from the JS backend: the Lua factory takes two arguments (not three; the JS one also threads the module name), and the Lua fixture ignores the force-call line number. Comments only; no change to generated code. Continues #44.
There was a problem hiding this comment.
Pull request overview
This PR continues the #44 “Notes” effort by documenting the cross-module laziness runtime contract (the ABI between the CoreFn laziness transform and the Lua runtime fixture) and updating a couple of previously-stale explanatory comments, with no intended change to generated code or goldens.
Changes:
- Added
Note [The runtimeLazy calling convention]to the Lua fixture to document thePSLUA_runtime_lazycurried convention and the memoization/cycle-detection scope invariant forstate/val. - Added a citable anchor
Note [Laziness transform for recursive binding groups]toCoreFn.Laziness. - Updated two existing comments to reflect Lua-vs-JS backend differences (factory arity and fixture line-number usage).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| lib/Language/PureScript/CoreFn/Laziness.hs | Adds a named Note anchor and updates commentary around runtimeLazy factory/force-call expectations. |
| lib/Language/PureScript/Backend/Lua/Fixture.hs | Documents the runtime-lazy calling convention and the required closure scoping for memoization/cycle detection. |
| changelog.d/20260625_191608_unisay_notes_laziness.md | Adds a changelog fragment describing the documentation additions/clarifications. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Continues #44, the laziness batch. The runtime-lazy path is the part of the compiler most exposed to silent breakage (the bug fixed in #126 lived here and went unnoticed because nothing documented or tested the contract). This batch documents that contract and corrects two stale comments. Comments only, so generated code, goldens, and eval oracles are unchanged.
Note [The runtimeLazy calling convention]inBackend.Lua.Fixture. The fixture side had no comment at all. The Note spells out the curriedPSLUA_runtime_lazy(name)(init)(line)shape, and in particular whystateandvalmust live in thefunction(init)closure rather than the forcing thunk (declaring them in the thunk is exactly what broke memoization in fix: PSLUA_runtime_lazy did not memoize (state reset on every force) #126). It also points back at the two transform sites that must keep the arity in step.Note [Laziness transform for recursive binding groups]inCoreFn.Laziness. The module had a thorough overview comment but no titled anchor, so nothing could cite the transform by name. This adds a short anchor that points at the existing prose.Corrected two comments inherited from the upstream JS backend that no longer match this port: the factory is applied to two arguments here (identifier, thunk), not three (the JS backend also threads the module name), and the Lua fixture ignores the line number passed to a force call (the JS backend uses it in the loop error message).
A note on scope
CoreFn.Lazinessis adapted from the upstreampurscompiler, and the issue asks to weigh divergence before retitling its comments. The delay/force and USE-INIT/USE-USE/USE-IMMEDIATE rules there are already documented thoroughly and are only cited from within the file, so I deliberately left that prose untouched rather than wrap it inNoteblocks for marginal intra-file benefit. The cross-module contract (the runtime-lazy convention) is where the citable Note earns its keep, and the fixture half of it is our own code.Checklist
changelog.d/fragment for any user-facing change (scriv createin the dev shell), or this change ships nothing releasable (CI, docs, or an
internal refactor).
nix develop),fourmolu -i lib/ exe/ test/andhlint lib/ exe/ test/are clean.cabal test allpasses; structural goldens werere-accepted on purpose if codegen moved (
PSLUA_GOLDEN_ACCEPT=1), andeval/golden.txtstill holds.