REBOL3 tracker
  0.9.12 beta
Ticket #0001521 User: anonymous

Project:



rss
TypeWish Statussubmitted Date12-Mar-2010 23:56
Versionalpha 97 CategoryError Handling Submitted byBrianH
PlatformAll Severityminor Prioritynormal

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 ton/a Fixed in- Last Update12-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 -