GC> Can a function have a variable number of arguments?

AM> No. But you can simulate it, by using 'any-type! function specifiers and passing 
unset! as arguments. Better is to use refinements.

LM> Yes, a function can have a variable number of arguments. Do is such a function, as 
e.g. in:

take-n: func [n /local spec] [
    spec: copy []
    for i 1 n 1 [
        append spec to word! append copy "a" to string! i
        ]
    func spec reduce [
        :reduce append reduce [
            to lit-word! append copy "take"to string! n
            ]
        spec
        ]
    ]
LM> do take-n 4 1 2 3 4
LM> == [take4 1 2 3 4]

LM> , where Do took 5 arguments.

AM> Actually, 'do took only one argument, the value returned from 'take-n which had 
the argument "4"), which happened to be a function that is evaluated by 'do that could 
take the next four arguments "1 2 3 4".

LM> Think for the second time, please. Let's make sure, how many arguments we have to 
take:

make-sure1: func [
    {This function takes just one argument}
    f
    ][
    ; evaluate the argument
    f
    ]
make-sure1 take-n 4 1 2 3 4

The result:
** Script Error: f is missing its a1 argument
** Where: make-sure1
** Near: f

make-sure2: func [
    {This function takes five arguments}
    f a2 a3 a4 a5
    ][
    ; evaluate f
    f a2 a3 a4 a5
    ]

make-sure2 take-n 4 1 2 3 4

The result:
== [take4 1 2 3 4]

LM>Conclusion: Do had to take five arguments to yield the correct result.

AM>Actually, I disagree. 'Do only took one argument. The function returned by 'take-n 
takes the four arguments. Rebol functions are a bit more active than in conventional 
languages. Take for example, this function:
        fget: func [:a][probe :a]
    It doesn't do much, not even _evaluating_ it's 'a argument. Here's a small session 
at Rebol console:

>> fget: func [:a][probe :a]
>> fget 1 + 2
1
== 3

Why did "1" get printed? And why was the result of 3 printed _after_ the "1"?

Here's another function:
        feval: func [a][probe :a]
    Note that I've dropped one colon out in the "function spec". Therefore 'a is 
evaluated. Here's the Rebol console session:

>> feval: func [a][probe :a]
>> feval 1 + 2
3
== 3

Note that both cases, the line:
        probe :a
    never evaluates 'a. So where does 'a get evaluated? Effectively here:
        func [a]
    More exactly, 'a is evaluated inside the brackets after "func". Or perhaps better 
to say that an evaluated argument in a function processes or evaluates the input 
stream of values until a natural stopping point is reached. In other words, the input 
stream reduces down to a value that is not a func or prefix operator (effectively a 
function) and isn't a value followed by a binary operator value. The input stream of 
values is also terminated by the presence of a right square bracket. Because 
"continuations", IIRC, aren't in Rebol, the function argument evaluation mechanism 
can't "leap out" of the function body and resume processing the "upper" or "outer" 
level input stream of values.

So the error message:

** Script Error: f is missing its a1 argument
** Where: make-sure1
** Near: f

means what it says, and 'do only has one argument.

I hope that helps!

Andrew Martin
-><-


-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to