arc-js icon indicating copy to clipboard operation
arc-js copied to clipboard

Is there a way to access on-err?

Open awwx opened this issue 7 years ago • 4 comments

I see that on-err is used in arc.arc, but it doesn't appear to have been exported into the user namespace:

arc> on-err
Error: Unbound variable on-err

Is there a way to import it from arc?

awwx avatar Feb 09 '17 16:02 awwx

No. Arc-js is not supported such a feature yet. Is it a hook on error occurred?

smihica avatar Feb 11 '17 13:02 smihica

Yes, in Arc 3.1 it's the equivalent of a try-catch block:

(prn "returned: "
  (on-err
    (fn (e)
      (prn "caught error: " (details e))
      123)
    (fn ()
      (prn "before")
      (err "foo")
      (prn "not reached")
      "would return this if an error hadn't been thrown")))
before
caught error: foo
returned: 123

The second argument is called, and if it doesn't throw an exception, on-err returns what it returns. If it does throw an exception, the first argument is called with the exception, and on-err then returns what that function returns.

In Arc 3.1, e is the Racket exception object, and (details e) returns the message the exception was thrown with. In JavaScript, e could perhaps be the JavaScript Error object (if that makes sense for the implementation), and (details e) could return e.message.

awwx avatar Feb 11 '17 14:02 awwx

Ok. I see. thanks.

But arc-js doesn't have try-catch block yet. It runs on original virtual machine that doesn't support it.

But arc-js has ccc (call/cc). So. you can do like this.

(ccc (fn (cc)
           (let throw (fn (x) (cc x))
              (throw 'err))))

and catch macro is also provided (expanded as above)

(catch (throw 'err))

I know that this feature is not sufficient for your purpose. This cannot catch (throw 'err) not only on inner calls but on JS calls.

To support it, we must implement try-err opcode (and also unwind-protection) on vm. and all primitive functions must be wrapped by the feature. It will be a bunch of works I think.

smihica avatar Feb 12 '17 07:02 smihica

It's worse than that, actually. To work with continuations, on-err only catches errors thrown within the dynamic extent of its execution.

If the code inside of an on-err invokes a continuation, and that code throws an error, that won't be caught by the on-err... but if the continuation had been captured at a point that had its own on-err handler, that handler would be invoked.

To be able to switch which error handler is active when a continuation is invoked, you'd need to implement dynamic binding like Racket's parameters or Scheme's dynamic-wind.

err and on-err wouldn't necessarily need to throw and catch JavaScript exceptions. If for example (car 10) called (err "10 is not a cons type"), then error handling could work inside the virtual machine without having to throw or catch JavaScript exceptions.

But implementing dynamic binding would be a big project ;)

awwx avatar Feb 12 '17 13:02 awwx