Where? Actually, there are two: CATCH function and [catch] function 
attribute.

===The CATCH function

This function essentially enables us to immediately finish a complicated 
evaluation.

Sample code

    catch [
        ; doing complicated evaluation...
        if done? [throw result1]
        ; more evaluations...
        if done? [throw result2]
        ; more evaluations...
        ; now we are done for sure
        result3
    ]

Similar effect can be achieved using ANY, ALL or CASE functions, but in 
the general case CATCH is the most appropriate for the job.

When using "embedded" CATCH evaluation, we can use the CATCH/NAME 
refinement to be able to specify the target for the desired results as 
follows:

    catch/name [
        ; ...
        catch/name [
            ; ...
            if done-a? [throw/name result 'a] ; this is meant for the 'a 
CATCH (the "outer" CATCH)
            ; ...
            if done-b? [throw/name result 'b] ; this is meant for the 'b 
CATCH (the "inner" CATCH)
            ; ...
            result-b
        ] 'b
        ; ...
        if done-a? [throw/name result 'a]
        ; ...
        result-a
    ]

===The [catch] function attribute

This attribute is meant to enable "above standard" error handling in 
functions.

Example: let's suppose we need a HANDLE function to handle every integer 
number except for 66. We consider it an error to call the HANDLE 
function with number 66 as its argument. Code:

    handle: func [
        [catch]
        argument1 [integer!]
        argument2 [block!]
    ] [
        if argument1 = 66 [throw make error! "number 66 not allowed as 
argument1"]
        do argument2
    ]

Now expression

    handle 1 ["OK"]

yields "OK", while

    handle 66 ["OK"]

is an error.

===Comparison

*the [catch] function attribute has a different purpose than the CATCH 
function.

*there isn't a similar "mechanism" of discerning the meaning of THROW 
for embedded functions

===Interference

An embedded [catch] - attribute function cannot discern the meaning of 
THROWS and it catches all throws as far as they are throwing errors. 
Example:

    index: 1
    block: copy ["OK"]
    insert tail block make error! "error"
    type? catch [
        ; ...
        handle 1 [throw pick block index]
    ]

So far so good, but if we change the first line to

    index: 2

, the interference will appear. We may ask whether the /NAME refinement 
could help, but the answer is negative as Romano found out.

===Solution

I offered TFUNC functions to solve the throw issue (as well as some 
other issues) for embedded functions earlier. (see 
http://www.compkarori.com/vanilla/display/Function-Attributes).

The interference between [catch] and CATCH can be solved by using local 
throws too, but some users may find this solution uncomfortable.

A simpler solution might use /NAME refinement for THROW, but that should 
be extended to enable us to specify an appropriate catch name for 
[catch] functions too. In that case I think, that it would be great if 
the name comparison was using =? not just = to use the full power of Rebol.

The End

PS: I am curious, whether you prefer a "local-word" solution or a /NAME 
solution, so consider this a user poll.

-Ladislav
-- 
To unsubscribe from the list, just send an email to 
lists at rebol.com with unsubscribe as the subject.

Reply via email to