Delimited Continuations: Implement `abort#` to avoid copying the continuation
Summary
The delimited continuation primops can be used to implement an exception mechanism similar to raiseIO#
and catch#
.
However, it is presently much more costly to do so, because the equivalent of catch# (E[raiseIO# exc]) handle
(which is roughly prompt# exc_prompt_tag (E[control0# exc_prompt_tag (\_k -> handle exc)])
) will copy the entire stack frame E
even though the continuation k
is always discarded.
I suggest we provide a primop abort# :: PromptTag# a -> a -> State# RealWorld -> (# State# RealWorld, b #)
as proposed by @lexi.lambda in #24165 (closed). The semantics of abort# tag e s
is that of control0# tag (\_k -> e) s
, but abort#
can be implemented without copying the stack.
Bonus: implement a custom rewrite rule that rewrites control0 tag (\_k -> e)
to prompt# tag e
when _k
is dead, so that this optimisation is done automatically by GHC.