Are there any other languages that allow the calling scope to specify how lower-level functions handle errors without unwinding the stack?
Are there any other languages that allow the calling scope to specify how lower-level functions handle errors without unwinding the stack?
While it isn't a mainstream language by any means, a scheme dialect called muSE [1] that I developed for writing logic for automatic music video construction supports such resumes and retries. [2]
[1] https://code.google.com/p/muvee-symbolic-expressions/
[2] https://code.google.com/p/muvee-symbolic-expressions/wiki/Ex...
(Apologies for shameless plug)
-- edit: I just saw that the clojure library "ribol" has an api design similar to muSE's in principle. A couple of design comments though -
1. The "on blah blah" is too much syntax for this. It prevents direct sharing of handlers between similar situations. Function argument pattern matching ought to be enough.
2. The retry options mechanism is somewhat limited - the options seem to apply only at the raise point itself (disclaimer: I've only had a quick glance at ribol). It is more useful to have multiple retry options at different scopes so you can partially unwind, try something, if that doesn't work unwind some more (perhaps involving cleanup), try something else, etc.
I think muSE's design is better on both these fronts.
"It's not Lisp!"
$ perl6
> $*PERL<name>;
rakudo
> $*PERL<compiler><ver>;
2014.03.01
> { CONTROL { print 1; $_.resume }; print 2; warn; say 3 }
213
ref: https://news.ycombinator.com/item?id=7192294For a perl5 Condition System see this implementation - https://metacpan.org/pod/ConditionSystem
http://p3rl.org/Worlogog::Incident http://p3rl.org/Worlogog::Restart
which uses Return::MultiLevel to do stack unwinds that can pass through try/catch constructs.
Any language with continuations can have it added as a library. Of course, not a lot of popular, non-Lisp languages these days have continuations... (Ruby kinda does -- it was a language-level feature in 1.8 but has been sidelined since as non-MRI implementations generally don't support them.)
https://docs.eiffel.com/book/platform-specifics/exception-me...
though honestly Ribol is probably a better bet---just wanted to show that this kind of thing can be done as a library without too much complication.
Dylan (http://opendylan.org/) has them, but that's because some of the same people who standardized Common Lisp went on to design Dylan.
another possible answer - Erlang.
While the look of the condition/restart scheme may be very different, such a condition/restart protocol can be implemented as message passing with a known global "condition handler" process I think.
A "raise" function can be implemented as a message-send to the condition handler process followed by an immediate wait-for-response. The handler process may terminate the raising process, replace its value with something, etc. depending on the installed handlers.