arc-js
arc-js copied to clipboard
Is there a way to access on-err?
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?
No. Arc-js is not supported such a feature yet. Is it a hook on error occurred?
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
.
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.
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 ;)