spec-conditions.md §4 gains the rule the shadowing bug was hiding: a handler
matches by name, a debugger identifies by position, and the two are not the
same question. With it, the snapshot — a position means nothing against a
stack that moves — and the fact that a visible restart may still be
unreachable, which §6's explicit lowering makes possible.
§3 records the open one: a clause should carry a report string.
is what invoke-restart needs and not what a person reading a list needs. It
wants settling before restarts with parameters, which is where a bare name is
least sufficient.
conditions.org had the break loop under "Not yet", which it has not been for
some time, and now says why find-restart and compute-restarts still are: they
are blocked on a Restart type and a list to return one in, not on effort.
plan.org now says every Flan function carries the transfer channel, that
uniformity is what keeps indirect calls and hot reload ABI-safe, and that a
later optimisation cannot change the ABI. spec-conditions.md §6 still read the
other way round - escape analysis deciding which functions are
transfer-transparent, with the rest paying nothing - which describes a
signature that depends on an analysis, and a cell cannot hold one of those.
So the analysis is demoted to what it can still honestly do: a function that
provably cannot transfer need not check the channel after a call and can pass
the pointer straight through. It may not drop the parameter. NEXT.md said the
same thing as a for-later note and now says it is settled.
The stated reason was that native and wasm32 must behave identically, which is
misleading: we do not develop on wasm32 and only ever export to it. The reasons
that hold are all release-side. wasm32 cannot unwind without the exceptions
proposal, so the export would not work at all. Native unwinding is not cheaper
and is much less legible - every call becomes an invoke with a landing pad,
where a cmp/jne after a call reads like ordinary code, which will matter once
there is a disassembler. And one mechanism is one thing to get right, since the
acceptance table runs the same programs on both targets and compares a hash.
The channel is an out-parameter rather than a discriminated return value, which
§6 had left open. The return type then stays what the source says; a
discriminated return would repack every ret, turn an aggregate return into an
sret call, and nest inside the discriminated return (Option T) already is. One
pointer threads down the chain, so a callee writes the target into its caller's
own slot and each frame only checks and returns early - reusing the existing
return path and therefore §5's defers.
A single global would be more legible still, with no signature change at all,
but it is not re-entrant: §5 runs defers during a transfer, so a defer that
signals and invokes a restart would start a second transfer over the first.