REBOL3 tracker
  0.9.12 beta
Ticket #0001520 User: anonymous

Project:



rss
TypeWish Statussubmitted Date12-Mar-2010 22:59
Versionalpha 97 CategoryNative Submitted byBrianH
PlatformAll Severityminor Prioritynormal

Summary CATCH /name true option
Description CATCH/name true would catch all THROW and THROW/name of any words thrown. This option would mostly be used for test code and calling third-party code from robust frameworks.

This would probably be a rarely used option, as normally you only want to catch the stuff you specify that you want to catch. However, in those cases where you need this you will really need this.

CATCH/name could be combined additively with the /quit and /halt options - there would be no conflicts. The logic! type would be added to the typespec of the word argument. CATCH/name false would be a noop, not catching anything, though /quit and /halt would still add to that. Sorry about the noop, but it made no sense to do CATCH/name none and have that mean all throws, and logic! has two values - perhaps it could be used for debugging.

See #1518 for the other part of this proposal.
Example code
>> catch [throw/name 1 'foo 'not-reached]
** Throw error: no catch for throw: make error! 2
>> catch/name [throw 1 'not-reached] true
== 1
>> catch/name [throw/name 1 'foo 'not-reached] true
== 1
>> catch/name [throw 1 'reached] false
== reached
>> catch/name [throw/name 1 'foo 'reached] false
== reached

Assigned ton/a Fixed in- Last Update12-Nov-2010 10:10


Comments
(0002098)
abolka
13-Mar-2010 23:34

If current CATCH behaviour is changed as described in #1518, we'll definitely need a possibility to CATCH all THROWS, whether named or not. So +1 for a CATCH/all catching all THROW unwinds.

I strongly disagree that CATCH/all should catch other (non-THROW) unwinds as well. This would be highly counterintuitive as the obvious and primary use of CATCH is to catch THROWs. I think code such as

run-plugin: func [f [any-function!]] [
catch/all [
return apply :f []
]
"ERROR: f tried to THROW"
]

is quite conceivable for an intermediate REBOL user to write. I don't want to explain to this hypothetical user that CATCH/all not only catches all THROWs but also "disables" RETURN without obvious reason.

Whether a facility for catching BREAK/CONTINUE/RETURN/EXIT unwinds is needed at all, will be a direct result of how bug #1506 is resolved. In any case, _if_ such a facility is implemented, it should be under a separate name, such as CATCH/unwind.

This would result in:

catch: Catches an unnamed throw
/name: Catches a named throw
/all: Catches all throws, named and unnamed
/unwind: Special catch for the BREAK, CONTINUE, RETURN, EXIT natives
/quit: Special catch for the QUIT native

To catch absolutely all unwinds catchable (i.e. excluding QUIT/now and HALT, as suggested by Brian) one would therefore use CATCH/all/unwind/quit.
(0002103)
BrianH
14-Mar-2010 22:12

"as described in #1518"

That term "unwind" refers to the implementation of those functions; it's a little too geeky to use as a option name here, too hard to explain. Perhaps /other would be better for abolka's revision if that gets adopted.

On the other hand, if the RETURN and EXIT functions go definitional and stop being normal unwinds, and we don't catch HALT and QUIT/now, that would leave just QUIT, BREAK and CONTINUE. If that is the case then it's not worth the hassle to catch anything other than THROW and THROW/name with CATCH/all. CATCH/quit and LOOP have no BIND/copy overhead so we can use them directly in a CATCH-ALL mezzanine. The only ones with overhead to catch otherwise are RETURN and EXIT, which usually need to be caught by creating a function and executing it, and wouldn't work at all to catch unhandled RETURN and EXIT if they are definitional.

The revised proposal would then be to have CATCH catch THROW (but not THROW/name); CATCH/quit catch QUIT (but not THROW, same as current behavior); CATCH/name catch THROW/name of the same name; CATCH/all catch THROW and THROW/name for all names (but not QUIT); and CATCH/all/quit catch QUIT, THROW, and THROW/name for all names. And CATCH/name/quit would probably ignore the /name option and not catch THROW/name, the same as it behaves now.
(0002783)
BrianH
4-Nov-2010 08:17

OK, time to scale back this proposal. We already have a way to catch RETURN and EXIT (DOES), BREAK and CONTINUE (LOOP 1), THROW without /name (CATCH), and QUIT (CATCH/quit). #1742 proposes a way to catch HALT (likely CATCH/halt), and #1743 would deal with QUIT/now (by getting rid of it). So we don't need to catch those with this proposal, they're covered, and we want to be able to catch those things separately.

We need to rethink CATCH. I think the best model is to have the default be minimal, with CATCH only catching THROW. CATCH/quit would only catch QUIT. CATCH/halt would only catch HALT. CATCH/name word would only catch THROW/name of the EQUIV? word. CATCH/name true would catch all THROW and THROW/name, with whatever words. And you can combine the options in an additive way, with CATCH/quit/halt/name true catching QUIT, HALT, THROW and THROW/name for all names. No other options needed, no potentially conflicting options.

I'm changing this proposal to just the CATCH/name true variant. #1742 can be CATCH/halt, and we have CATCH/quit already (though see #851 and #1743). And #1744 would make CATCH/name word more useful.
(0002802)
Ladislav
5-Nov-2010 08:42

I still oppose the #1518. A locally bound THROW looks preferable (since it "automatically" looks for its intended target, without needing additional arguments).

The fact that we can catch all THROWs using CATCH is good, the only thing that may be questionable is the current way how the CATCH function is used. But, the habits should not force us to complicate our code, the interpreter, and the language.
(0002808)
BrianH
5-Nov-2010 22:19

Catching all throws is a rarely needed feature, only needed by makers of test frameworks and callers of untrusted code (like you, Ladislav).

Most people need to be able to skip past catches, which is the best reason for having THROW/name, and because of #1518 they can't. This means that for most uses, there is no difference between THROW/name and THROW. But there *needs* to be a difference, there needs to be a purpose for having THROW/name that justifies its existence, otherwise we should drop the feature altogether. And there is no reason we should drop such a potentially useful feature as THROW/name.

The purpose of #1518 is to make the most commonly needed behavior the default, and the purpose of this ticket is to make the more rarely needed behavior of catching all throws an option instead. Both types of behavior are important in different circumstances, but being able to get past CATCH by default is more important for most programmers than the catch-all behavior, even though the catch-all behavior is more important for *you*.

You have stated repeatedly that it is provable that you can do the same stuff without such changes, and I have seen the code that you use to prove this. The problem is that is really advanced code, and most people other than you and maybe a half-dozen others (including me) understand what you are writing, let alone would be able to write such code themselves. And why should they, when it would be so much easier to just make a simple feature for them to use without needing to understand how it is done? And so such a feature was added: THROW/name. But it doesn't work well enough to be useful because of the CATCH bug, which you consider to be a "feature" for your code, but for most people basically disables most of the THROW/name feature, so much so that it mostly isn't used anymore.

There's no reason we can't support both uses, yours and the rest of the world's. We just need to change the default.

And once we change that default, we won't need to do it again. Once THROW/name works, we can use it to implement in mezzanine all of the obscure requests for new control functions. And once this ticket and #1742 and #1743 are implemented, we will have a clearly defined way to catch everything if we really need to. No more arms race, everyone wins.
(0002847)
maxim
12-Nov-2010 08:48

since I also think that #1518 is essential to make more advanced code patterns easy to implement by non god-like rebolers, this wish is also pretty important IMHO.

in addition to the above proposal, I think that
CATCH/name [...] false could be used to catch ONLY /name throws but any word matches.

the idea being that the logic argument means: "also catch non-named throws?"

with this setup, we effectively can catch any combination of unnamed, specific or all named and both (named and unnamed) throws.
(0002853)
BrianH
12-Nov-2010 10:10

That sounds good to me, Maxim.

Date User Field Action Change
23-Mar-2013 03:41 Ladislav Comment : 0002802 Modified -
12-Nov-2010 10:10 BrianH Comment : 0002853 Added -
12-Nov-2010 08:48 maxim Comment : 0002847 Added -
5-Nov-2010 22:33 BrianH Comment : 0002808 Modified -
5-Nov-2010 22:23 BrianH Comment : 0002808 Modified -
5-Nov-2010 22:22 BrianH Comment : 0002808 Modified -
5-Nov-2010 22:19 BrianH Comment : 0002808 Added -
5-Nov-2010 08:45 Ladislav Comment : 0002802 Modified -
5-Nov-2010 08:42 Ladislav Comment : 0002802 Added -
4-Nov-2010 08:44 BrianH Category Modified Error Handling => Native
4-Nov-2010 08:44 BrianH Code Modified -
4-Nov-2010 08:44 BrianH Description Modified -
4-Nov-2010 08:44 BrianH Summary Modified CATCH /all option => CATCH /name true option
4-Nov-2010 08:17 BrianH Comment : 0002783 Added -
4-Nov-2010 07:52 BrianH Comment : 0002779 Removed -
3-Nov-2010 20:22 BrianH Comment : 0002779 Added -
15-Mar-2010 00:16 abolka Comment : 0002098 Modified -
14-Mar-2010 22:37 BrianH Comment : 0002103 Modified -
14-Mar-2010 22:26 BrianH Comment : 0002103 Modified -
14-Mar-2010 22:19 BrianH Comment : 0002103 Modified -
14-Mar-2010 22:18 BrianH Comment : 0002103 Modified -
14-Mar-2010 22:12 BrianH Comment : 0002103 Added -
13-Mar-2010 23:37 abolka Comment : 0002098 Modified -
13-Mar-2010 23:36 abolka Comment : 0002098 Modified -
13-Mar-2010 23:36 abolka Comment : 0002098 Modified -
13-Mar-2010 23:34 abolka Comment : 0002098 Added -
12-Mar-2010 23:20 BrianH Description Modified -
12-Mar-2010 23:20 BrianH Code Modified -
12-Mar-2010 23:20 BrianH Description Modified -
12-Mar-2010 22:59 BrianH Ticket Added -