People do not generally want to capture the entire continuation, they want delimiters. Delimited continuations are a superset of call/cc and vastly more useful, more performant and easier to understand.
The call/cc interface is completely backwards as well. It's like throw/catch but the exception handler is specified by throw instead of catch. Totally mind bending and unintuitive.
This continuation business is just resumable exceptions. Would have been a lot easier for people to understand and use had they just called it that.
try:
print(10 + throw("error"))
catch error, continuation:
continuation(10) # Makes throw return 10, prints 20
Despite call/cc being generally understood as not good it's still something you would expect to work in a Scheme implementation. In the Scheme-on-Wasm implementation I work on we emulate call/cc in terms of delimited continuations. Passes r7rs benchmaks that make use of call/cc.
Seems kind of backwards to call them resumable exceptions because delimited continuations are the primitive upon which an exception system can be built but yeah maybe it would make sense to programmers that already understand exceptions. I like the prompt metaphor, myself. https://www.gnu.org/software/guile/manual/html_node/Prompts....
> we emulate call/cc in terms of delimited continuations
Seems reasonable.
> I like the prompt metaphor, myself
Me too. I really like Guile's prompts. They are delimited and structurally similar to my example above, only they're even more powerful since they have tags which lets programmers unwind to specific delimiters!
I'm implementing this stuff in my lisp right now. The prompt primitive pushes a special continuation marker stack frame which also contains a value. The tagged prompts use symbols as the tag, untagged prompts use nil.
> Seems kind of backwards to call them resumable exceptions
This is is the analogy that enabled me to finally understand this continuation stuff. Alexis King's keynote shows that they are equivalent:
Nope. I was thinking about implementing call/cc; there is a neat trick involving first doing a CPS transformation to the source, then providing call/cc as a builtin function that more-or-less just grabs the continuation argument and returns it. This would slot pretty easily in between expansion and code gen and the code generator would remain mostly untouched.