A handler's capture is the non-escaping kind
The refusal said milestone 5, which lumped it in with escaping closures - and plan.org has just deferred those until a concrete use case appears. A handler frame does not outlive the function that pushed it, so what a handler clause needs is spec-memory.md's case 2, a non-escaping fn capturing by value into a stack environment, which is settled rather than deferred. Worth recording before anyone schedules it, because open decision #5 says in as many words that without this conditions are not worth building, and the deferral it just received does not apply to it.
This commit is contained in:
parent
5980b5b60f
commit
c322ef60bf
16
NEXT.md
16
NEXT.md
@ -923,10 +923,18 @@ Three decisions worth keeping:
|
||||
Which gives the two refusals, both by the house rule rather than by accident:
|
||||
|
||||
- **A handler cannot see the establishing function's locals.** That is a
|
||||
closure with an explicit environment — milestone 5's work — so a reference to
|
||||
one is refused *for that reason* rather than reported as an unknown name.
|
||||
Globals and the condition are in scope, which is what the accumulation case
|
||||
needs.
|
||||
closure with an explicit environment, so a reference to one is refused *for
|
||||
that reason* rather than reported as an unknown name. Globals and the
|
||||
condition are in scope, which is what the accumulation case needs.
|
||||
|
||||
What it needs is narrower than it looks, and worth getting right before
|
||||
anyone schedules it: a handler frame does not outlive the function that
|
||||
established it, so this is spec-memory.md's **case 2** — a non-escaping `fn`
|
||||
capturing by value into a stack environment — and *not* the escaping closure
|
||||
that plan.org's open decision #5 defers until a concrete use case. Case 2 is
|
||||
settled, and #5 says in as many words that without it "conditions are not
|
||||
worth building". So the biggest usability limit in conditions is not behind
|
||||
the thing that was just deferred.
|
||||
- **`return` inside a `handler-bind` body is refused.** The frames are popped
|
||||
on the way out and an early exit would leave them on the stack pointing into
|
||||
a function that has gone. Same shape as `defer` inside a block.
|
||||
|
||||
14
lib/check.ml
14
lib/check.ml
@ -126,9 +126,11 @@ let lookup ctx name = List.assoc_opt name ctx.scope
|
||||
|
||||
(* A handler clause is lifted into a function of its own, so the establishing
|
||||
function's locals are simply not there. Capturing them is a closure with an
|
||||
explicit environment — milestone 5's work — and until it exists a reference
|
||||
to one is refused for the reason it is really refused for, rather than as a
|
||||
name nobody has heard of. *)
|
||||
explicit environment — spec-memory.md's case 2, a non-escaping [fn] capturing
|
||||
by value into a stack environment, since a handler frame does not outlive the
|
||||
function that pushed it — and until that exists a reference to one is refused
|
||||
for the reason it is really refused for, rather than as a name nobody has
|
||||
heard of. *)
|
||||
let captured ctx loc name =
|
||||
if ctx.in_handler && List.mem_assoc name ctx.outer then
|
||||
raise
|
||||
@ -539,9 +541,9 @@ and block ctx ?want loc body =
|
||||
function of its own and reached through a pointer.
|
||||
|
||||
Which means it cannot see the establishing function's locals. Capturing them
|
||||
is a closure with an explicit environment, which is real work and is
|
||||
milestone 5's; until then a reference to one is rejected by name rather than
|
||||
silently resolving to something else. Globals and the condition itself are
|
||||
is a closure with an explicit environment — the non-escaping kind, captured
|
||||
by value onto this frame — and until that exists a reference to one is
|
||||
rejected by name rather than silently resolving to something else. Globals and the condition itself are
|
||||
in scope, which is enough for the accumulation case §1 is about.
|
||||
|
||||
The body may not [return] either. The frames are pushed and popped around
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user