Conditional catch clause

Herby Vojčík herby at mailbox.sk
Wed Dec 19 10:05:22 PST 2012



Brandon Benvie wrote:
> The magical quality that throw has is its ability to end multiple call
> frames at once. Much like a second continuation channel, or the error
> channel in a promise, it escapes past any number of listeners on the
> normal channel, only stopping at the first listener on the error channel.

Yes. The problem is, it is only one global channel. Thus, all exception 
sent down to it can be in different contexts, but must be multiplexed 
into that one channel.

For example in Amber, non-local returns are emulated via throw. A try is 
cheap, but catch is expensive, so when non-local return happens nested 
in five more methods that also include non-local return, five 
catch/rethrow happens.

So to answer David's questoin, this is definitely a case for 
_something_like_ conditional catch clause.

But these channels are better idea. I think we may have multiple 
exception-like channels. One is present by default (the classical 
throw/catch), but one could have more parallel ones.

Then I can assume `throw foo` is the sugar for 
Reflect.errorChannel.raise(foo). And syntax of try could be enhanced to, 
say:

   try(channel) { .... } catch (ex) { .... } finally { ... }

Then normal `try {...` is sugar for `try(Reflect.errorChannel) {...`.

And one could simple `let myChannel = new TryCatchChannel();` and use 
it. It can have some minimal api, like

   channel.raise(exception);
   channel.pass(); // this does not break the original stack

and others are also interesting, but are probably beyond any simple 
proposal, like:

   channel.defaultHandler = ex => console.log("Unhandled: "+ex);
   channel.resume(returnValueFromRaise); //fail if no raise is actually 
handled

etc.

Herby

P.S.: Maybe this could already be done with generator magic and yield; I 
did not research.


More information about the es-discuss mailing list