Ciao, Gabriele,

thanks for your ERROR explanation. Don't you think that CURRIED should have
worked as originally written (without the non-re-entrant bugs in Rebol)?

Instead of:
use [function] [
    function: :fnc
    ...
    func ...

One could write:
do func [[throw] /local function] [
    function: :fnc
    ...
    return func ...

, which seems non-static, but this probably wouldn't survive the garbage
collection too 8^(

Ladislav

 l> Request #1: This shows how CURRIED handles errors (argument C
 l> is not allowed, because it isn't between the formal args of
 l> FUN). Can somebody show me, how to MAKE ERROR! so, that I
 l> could say which args are incorrect - those in NONARGS).

>> formargs: [a b]
== [a b]
>> nonargs: [c]
== [c]
>> make error! compose/deep [script expect-set [(formargs)] [(nonargs)]]
** Script Error: Expected one of: a b - not: c.
** Where: make error! compose/deep [script expect-set [(formargs)]
[(nonargs)]]


I'd suggest to set the catch attribute for the function too.

 l> Request #2: I do'nt think this function is reliable (what a
 l> pity! - Jeff, Bo, anyone?), because when you look at source
 l> DFUN you see FNC in there, but FNC is argument of CURRIED and
 l> valid only until you evaluate CURRIED for the next time, due
 l> to the nonreentrant nature of function evaluation, problems
 l> with extents, garbage collector ... So Rebol shows exceptional
 l> expressibility, but worse implementation here...

curried: func [
    "Create curried functions" [catch]
    fnc [any-function!] "Function to be curried"
    args [block!] "Arguments of the curried fnc"
    /local formargs nonargs arguments body
] [
    formargs: first :fnc
    if not empty? nonargs: difference/only args formargs [
        throw make error! compose/deep [script expect-set [(formargs)]
[(nonargs)]]
    ]
    use [function] [
        function: :fnc
        arguments: difference/only formargs args
        body: compose [function (formargs)]
        func args reduce ['func arguments body]
    ]
]

>> test: func [a b] [print [a b]]
>> test-c: curried :test [c]
** Script Error: Expected one of: a b - not: c.
** Where: curried :test [c]
>> test-c: curried :test [a]
>> source test-c
test-c: func [a][func [b] [function a b]]
>> test1: test-c 1
>> test1 2
1 2
>> source test1
test1: func [b][function a b]
>> f: func [c d] [print c print d]
>> f-c: curried :f [d]
>> f1: f-c 1
>> source f1
f1: func [c][function c d]
>> f1 2
2
1
>> test1 2
1 2

This still suffers from a big problem (I'll leave the solution to
you as an exercise <big grin> >;-> ):

>> test2: test-c 2
>> test2 2
2 2
>> test1 2
2 2

(Hint: a function's context is static, unless the function is
recursive).

Regards,
    Gabriele.
--
o--------------------) .-^-. (----------------------------------o
| Gabriele Santilli / /_/_\_\ \ Amiga Group Italia --- L'Aquila |
| GIESSE on IRC     \ \-\_/-/ /  http://www.amyresource.it/AGI/ |
o--------------------) `-v-' (----------------------------------o




Reply via email to