Description
One of the "marketed features" of Myst is that any value can be raised as an exception. This is great for user-land code, letting raise
act like a more powerful break
, but can be a nightmare for consistency and extendability in libraries and frameworks.
I see a few aspects to this:
- Add core error types to the native library. This would include
NoClauseError
,MatchError
,ParseError
, etc. - Add standard library error types where appropriate. This would include things like
FileNotFound
,DivideByZero
, etc. (these are examples. Actual errors will probably differ). - Refactor existing code to use these types (see Only raise
RuntimeError
s from the Interpreter #98 for a start).
Additionally, an important part of rescuing errors is knowing where the error came from. With normal values as exceptions, this won't always be possible (e.g., integers don't have a callstack attached to them). For this, I have two ideas:
-
Add an optional second parameter for
rescue
that captures cause information separately. This would be similar to the result of thecaller
method that Ruby provides. This feels like it would need a distinguishing syntax to avoid confusion with passing multiple values:def foo rescue error, cause # `cause` includes the callstack of the error and location info. end
-
Assume a standard method name for getting callstack info in a rescue. This is implicit and I don't particularly like it, but avoids the confusion from above:
def foo rescue error cause.callstack.size # `cause` is basically a magic constant like `__LINE__`. end
I'm not super excited by either of those, but I'm leaning towards the first, at least as a temporary implementation.