Strawman: `Function.prototype.try` (or `Function.try`)

Isiah Meadows isiahmeadows at
Wed Aug 23 00:35:11 UTC 2017


BTW, I specifically avoided `type: "normal"`, etc., because only
`"normal"` and `"throw"` are exposed to JS in any significant capacity
- they're what you can detect using `try`/`catch`. The others are
internal-only exception-like values used in the spec to implement
breaking and loop continuation in its internal AST interpreter.
Although I said completions, I meant it loosely.

(All browser engines instead operate on control flow graphs to
generate bytecode, so they also only really use `"normal"` and

In addition, monads are a great way of introducing complexity into the
language, and absent pattern matching *at all* (or anything else
similarly extensible), let's save that rabbit hole for another time.

Here's some more specific responses inline:

On Tue, Aug 22, 2017 at 1:21 PM, Jordan Harband <ljharb at> wrote:
> I think if we wanted to add a "Result" type, we might want to do that
> holistically instead of having an arbitrary prototype method return an
> arbitrary object literal.
> It'd be really nice to have that type, but I'm not sure how easy it'd be to
> make a compelling case.

I like this, but the complicated monadic whatnot that was
*immediately* suggested is quite frankly *not* the ideal way to handle
this, since we already have standard exception handling.

What about something like this, just to start? Of course, there's
probably big things missing here, but just thought I'd get the ball
rolling a little.

class Result<T> {
    constructor(init: () => T);
    value: any;
    type: "return" | "throw";
    get(): T; // throws if `init` threw

(I'd rather start small than wind up with something over-engineered
and really bad.)

On Tue, Aug 22, 2017 at 2:08 PM, Sebastian Malton <sebastian at>
> wrote:
> 1. What is the difference between "normal" and "return"?

You get `"return"` when returning from a function. The spec implements
early returns using this (a special exception-like completion), since
it just interpret's the AST directly.

Engines don't actually use this method, though. They build a control
flow graph, and they lower `let`s into something not unlike `var`s, so
they don't actually need to have anything like a special exception to
handle these cases.

> Since try catching is not very efficient it would be better to have some sort of type.

V8 has been the exception, not the rule (no pun intended :-)) in
having very poor exception handling performance. Every other engine
has optimized them very well at this point. (Spidermonkey used to have
issues with functions that *threw* exceptions, but that's not as much
of a problem as it used to be, and it only deopt'ed once it actually

In addition, V8's new interpreter/compiler pipeline, Ignition and
TurboFan, no longer has this issue, and can fully optimize code with
`try`/`catch` in it.

On Tue, Aug 22, 2017 at 3:46 PM, Mike Samuel <mikesamuel at> wrote:
> Noone's answered yet, so I'll take a stab.
> An instruction that completes normally transfers control to the "next"
> instruction analogous to incrementing the program counter.
> An instruction that returns pops (modulo yield) a stackframe which includes
> resetting the program counter to its state prior to the call, unless there
> are protected regions containing the program counter in which case it jumps
> to the innermost.  Protected regions in EcmaScript correspond to try{...}
> for the most part.

>> 2. As previously stated a new type would probably be best since this can
>> be made much better then what is essentially a try/catch.
>> Since try catching is not very efficient it would be better to have some
>> sort of type. However, this leads to how to implement, it could just be a
>> class but then it could just be added manually. The real benefit to this
>> would be great integration with async/await and pattern matching
> Others are much more familiar with VM performance constraints, but IIRC, its
> not the catching that is inefficient, but associating the stackframe with
> the exception.
> Dispatching an exception within a stack frame just involves finding the
> innermost protected region containing the PC which is a binary search over a
> fairly small list of instruction indices.
> It sometimes matters whether you associate stack information with an Error
> on `new Error()` as in Java, or on throw as in Python but IIRC EcmaScript
> doesn't yet take a position on that.
> Throwing a non-Error-value also needn't incur the stack walk.
> _______________________________________________
> es-discuss mailing list
> es-discuss at


Isiah Meadows
me at

Looking for web consulting? Or a new website?
Send me an email and we can get started.

More information about the es-discuss mailing list