Comments on: Refining TRY exceptions
An refinement to try has been suggested (for a quite a while): to provide a way to distinguish an exception was thrown v.s. an error value was returned. It is an interesting issue.
First a quick review. As you know,
try [some code]
will evaluate the code and return the result. If an error occurs, it is thrown and caught by try, and the error value is returned.
You can write:
if error? err: try [some code] [handle err]
However, because in REBOL an error is a first class datatype. You are allowed to create, store, and return errors as actual values.
an-error: make error! "a simple error"
In R3, this does not cause an exception, it simple creates an error value. To force it as an exception:
But, in try, you now have an ambiguous evaluation case:
err: try [some code where an error exception happens]
err: try [make error! "some error"]
Both return an error value, but the first try had an actual exception, and the second did not. It simply returned an error value.
It has been suggested that we add a refinement to try that helps us to process the exception case:
value: try/except [some code] [handle the error]
However, that is not enough, the error handling block will often need to know the error value. This means the exception is actually a function:
value: try/except [some code] func [error] [handle the error]
When the exception occurs, the error handler function will be called, and that code will also provide the return value for the try.
Although this line seems a bit "wordy", it's the functional language way to do things like this.
It would be easy to create a mezzanine function to make the approach look more like switch:
value: try-except [some code] [
script zero-divide [handle this case]
script out-of-range [handle this case]
default [other cases]
This is done in many other languages, but it's just a wrapper, and may or may not be worthwhile as a standard function.
I posted some notes to the ticket #822|
I do not understand: in my copy of alpha-54, the line|
>> an-error: make error! "some text"
*does* cause an exception
I have seen the comment about first-class datatypes elswhere, but I thought it was a remnant of an earlier version of the implementation.
in my experience the only functions disarming the error are disarm, type? and error?
I take back my previous comment: I was thrown by the fact that the console *output* is identical for _make error!_ and _do make error!_, but the actual error is not put into system/state/last-error unless there is _do_
perhaps this is just a tiny bit confusing
PS I had to change my name since the system does not acept two consecutive comments from the same name
Meijeru: compare these:
make error! "some text" "OK"
do make error! "some text" "OK"
just testing the "two consecutive comments issue"|
That's correct. R3 does not use "armed" errors. They are much more "tame".
The FORM (PRINT) of an error appears as an error message ( not as an object, for that use MOLD and PROBE.)
This formatting feature makes it easy for users to capture errors and display them in standard format in their own windows, logs, etc.
Note, if you put another value on the test line, you can prove it's not an exception:
>> an-error: make error! "test" 123
there is a question, whether the two lines:
make error! "some text"
do make error! "some text"
should actually produce the same console output
There is also a question (ticket #828) about how the console output: |
>> make error! "some text"
** User error: "some text"
** Note: use WHY? for more about this error
Is incorrect, because system/state/last-error is not getting set, so WHY? won't work. Having the display be the same is fine, as long as last-error is set appropriately.
I prefer to just not show the WHY? note instead|
Alternatively, WHY? should plug a method to allow your own error description lists. But then comes the question of how to tie user errors from different modules to specific error description lists.|
I have been trying to find out myself where FORM gets the text for its error messages, e.g. where is 'zero-divide decoded into "attempt to divide by zero" etc.
this used to be clear in REBOL 2 but system/error does not anymore exist...
1. WHY? should not be displayed, unless it points to the same object.
2. We will need some system/options for WHY? in order to allow custom lists.
3. The error message catalog needs to be properly exported.
There is a subtle point here: you actually use the function to create an execution context around the error handler block that has access to the error.
One of the features that would solve this is "context injection" - extend the current context of the error block with the error value (and perhaps a bind to a default word).
Much like use in R2 (I know it is a closure in R3).
I can live with lambda the ultimate, but I'd rather see this solved with context the superior.
We've done that before (in R2), but I wasn't sure if users would approve. It's just a bit magical.
In summary, we could bind a word (like 'error) to the error object within the error handling block.
value: try/except [some code] [probe error]
Is everyone ok with that?
what about supplying an error word?
try [some code]
err [probe err]
looks very readable to me. (not in 3 lines of course. i was just emphasizing the structure)
i don't see problem with some magic for convenience but fixing the variable name smells like having keywords in a language..
Post a Comment:
You can post a comment here. Keep it on-topic.