Summary
Effect-handler-owned state held in a top-level mut cell diverges from the
identical program written inside fn main(). When the handler that owns the
mut state is installed across the C HTTP-callback boundary (a request handler's
perform resolving to the active handler), de-maining the program — moving the
mut cells and handle … in to module top level, where main is synthesised
from trailing statements — produces wrong output and lost state.
Repro
examples/tested/effects/http_state_levels.ospml (and its .osp twin) only
pass with an explicit main () = wrapper around the mut diskBytes/requests/ tasks/taskCount cells + the handle Persist/Metrics/Db/Log … in runDemo ().
Lifting the same mut + handle to top level (the de-mained form used by the
other 7 effects pairs) changes the observed output:
- expected (inside
main): server replied 201, shutdown counts reflect all writes
- actual (de-mained, top level):
server replied 200, state reset / counts wrong
The other effects examples (handler_scoping, resume_*, fiber_effects)
de-main cleanly with byte-identical output and IR, so the divergence is
specific to handler-owned mut state that crosses the C HTTP-callback
boundary at module top level.
Expected
A top-level script and the same code wrapped in fn main() must produce
byte-identical output and IR (the no-main invariant in
docs/specs/0023-LanguageFlavors.md [FLAVOR-ASSIGN] — main is synthesised from
trailing top-level statements, in both flavors). Handler-owned mut state must
survive across the HTTP/C-callback boundary regardless of whether the handler is
installed inside main or at top level.
Impact
- Blocks de-maining
http_state_levels (the canonical handler-owned-state-across-
HTTP example, cited in docs/specs/0017-AlgebraicEffects.md).
- Affects both flavors (
.osp and .ospml).
Notes
Surfaced while removing needless main wrappers from the spec/example set. The
spec examples in 0017 that use top-level mut + handler for pure effects
de-main fine; only the HTTP/C-callback-boundary case diverges, which points at
the callback-boundary handler-resolution path rather than top-level mut per se.
Summary
Effect-handler-owned state held in a top-level
mutcell diverges from theidentical program written inside
fn main(). When the handler that owns themutstate is installed across the C HTTP-callback boundary (a request handler'sperformresolving to the active handler), de-maining the program — moving themutcells andhandle … into module top level, wheremainis synthesisedfrom trailing statements — produces wrong output and lost state.
Repro
examples/tested/effects/http_state_levels.ospml(and its.osptwin) onlypass with an explicit
main () =wrapper around themut diskBytes/requests/ tasks/taskCountcells + thehandle Persist/Metrics/Db/Log … in runDemo ().Lifting the same
mut+handleto top level (the de-mained form used by theother 7 effects pairs) changes the observed output:
main):server replied 201, shutdown counts reflect all writesserver replied 200, state reset / counts wrongThe other effects examples (
handler_scoping,resume_*,fiber_effects)de-main cleanly with byte-identical output and IR, so the divergence is
specific to handler-owned
mutstate that crosses the C HTTP-callbackboundary at module top level.
Expected
A top-level script and the same code wrapped in
fn main()must producebyte-identical output and IR (the no-
maininvariant indocs/specs/0023-LanguageFlavors.md[FLAVOR-ASSIGN] —mainis synthesised fromtrailing top-level statements, in both flavors). Handler-owned
mutstate mustsurvive across the HTTP/C-callback boundary regardless of whether the handler is
installed inside
mainor at top level.Impact
http_state_levels(the canonical handler-owned-state-across-HTTP example, cited in
docs/specs/0017-AlgebraicEffects.md)..ospand.ospml).Notes
Surfaced while removing needless
mainwrappers from the spec/example set. Thespec examples in 0017 that use top-level
mut+ handler for pure effectsde-main fine; only the HTTP/C-callback-boundary case diverges, which points at
the callback-boundary handler-resolution path rather than top-level
mutper se.