Type | Wish | Status | submitted | Date | 12-Mar-2010 23:56 |
---|---|---|---|---|---|
Version | alpha 97 | Category | Error Handling | Submitted by | BrianH |
Platform | All | Severity | minor | Priority | normal |
Summary | RECOVER native function or CATCH/recover option |
---|---|
Description |
RECOVER would take two blocks of code. The first block would be evaluated and its return value, including propagating unwinds, would be saved temporarily. Then the second block would be evaluated. Then the saved return value from the first block would be returned from the function, allowing any unwinds to continue propagating. Unwinds from the second block can be ignored, though not triggered errors.
RECOVER would allow you to safely clean up after a block of code even if there are BREAK, EXIT, etc. functions in the code, without interfering with their operation. This would be useful in, for instance, the DO intrinsic function. It would be possible to make this a /recover option of the CATCH function instead, with the second block as a parameter. CATCH would then catch all unwinds, do the recovery block, then return any unwinds that it would otherwise not catch given whatever other options are also passed. This approach would save code in DO, for instance. We would not need to catch real errors with RECOVER because TRY/except can do this already with a function handler that retriggers the error after any cleanup code. Note: Because of bug #1509, ALSO currently works the way described here, though without the code being in blocks. We would need RECOVER to have the same effect where we actually want it, such as in DO. It would need to be native or an option of a native because otherwise you wouldn't be able to save the unwind value without causing it to propagate prematurely (see #1515 for details). |
Example code |
; RECOVER method recover [catch/quit code] [cleanup] ; CATCH/recover method catch/quit/recover code [cleanup] |
Assigned to | n/a | Fixed in | - | Last Update | 12-Nov-2010 10:07 |
---|
Comments | |
---|---|
(0002097)
BrianH 13-Mar-2010 00:36 |
For DO and other functions like it that need to CATCH stuff anyways, the CATCH/recover version would probably be faster and simpler. The RECOVER version would be more general though. If we had to pick just one then I'd pick CATCH/recover, because it already would have the code to catch unwinds. |
(0002836)
BrianH 11-Nov-2010 16:36 |
For some reason it took me a while to notice this, but QUIT and HALT don't propagate using the unwinding method that the other functions use. This means that a standalone RECOVER function might have a little difficulty catching QUIT and HALT and then knowing to propagate them. If this turns out to be the case then it should be noted as a known weakness of the RECOVER function.
If we do this as CATCH/recover, then that would cause CATCH to catch QUIT and HALT, do the cleanup code, then retrigger the QUIT or HALT. Then combining with /quit or /halt would stop the retriggering of QUIT or HALT, respectively. That would even work in DO and other functions like it. Note that if we switch to definitional return this won't catch those either, but that might be acceptable. Just document it. |
(0002848)
maxim 12-Nov-2010 08:57 |
very usefull for C++ like exception handling.
though it may be simulated with this trick: first reduce [catch/quit code cleanup] I use this a lot in R2 to force GC cleanup of all local words, even the return value. |
(0002852)
BrianH 12-Nov-2010 10:07 |
Maxim, that code relies on bug #1760. It's like #1519, but for REDUCE. |
Date | User | Field | Action | Change |
---|---|---|---|---|
12-Nov-2010 10:07 | BrianH | Comment : 0002852 | Added | - |
12-Nov-2010 08:57 | maxim | Comment : 0002848 | Added | - |
11-Nov-2010 16:45 | BrianH | Comment : 0002836 | Modified | - |
11-Nov-2010 16:36 | BrianH | Comment : 0002836 | Added | - |
13-Mar-2010 00:36 | BrianH | Comment : 0002097 | Added | - |
12-Mar-2010 23:56 | BrianH | Ticket | Added | - |