[REBOL] Re: [RWEBOL] HOF and system exploration
From: jan:skibinski:sympatico:ca at: 25-Oct-2002 14:21
Ladislav Mecir wrote:
> Hi Jan,
>
> argument counts aren't strict in Rebol. Did you read
> http://www.rebolforces.com/~ladislav/argstake.html ?
>
Hi Ladislav,
> argument counts aren't strict in Rebol. Did you read
> http://www.rebolforces.com/~ladislav/argstake.html ?
Sorry for the long answer but I think I owe it to
you.
I re-read the cited file just a while ago.
I do not understand the business with 'unset yet, so I'll
put this problem aside for a moment.
A question of of refinements just complicates the picture
but it is also tractable, so I'll let it be too.
I would also put aside the case with :-, since Rebol seems
to confuse itself sometimes by having a choice to interprete
:- either as the unary operator 'negate or the binary operator
'subtract. I came across such examples too. But if you
substitute :- by explicit 'subtract in your tests then
everything is OK.
But what disturbs me in your article is the last point
you are making about a variable number of arguments
which some functions, such as 'make and 'do, seem to take.
I have examined your tests regarding the 'do function:
args-taken? :do reduce [:- 1 2] ; == 3
args-taken? :do reduce [:make function! [] []] ; == 4
and came up with a conclusion that your tests here are
not properly chosen for the current version of your
'args-taken? function. You would either need to redesign
that function or use it with great care.
For a start, I would expect the result = 1 in either case,
-- not 3 and 4, as shown above.
By definition, the 'do function expects ONE argument only, which
is either a block of expressions, or a single expression
silently packaged inside a block.
If you modify the first test above as follows:
x: reduce [:+ 1 2] ; I replaced :- by :+ to avoid unary/binary
confusion
== [op 1 2]
args-taken? :do [x 99 sine 4]
== 1
then you end up with the argument count == 1, as expected
and also delivered by 'nargs:
nargs :do
== 1
Your 'args-taken? seems to check at runtime whether
a function being tested (here the 'do function) accepts
more arguments than officially described by 'help, or
computed by 'nargs. So when 'args-taken? is supplied
with a correct number of arguments - plus possible
extra garbage - it uses the 'do/next to operate only
on those arguments which are needed. But it fails
if the number of arguments is underspecified.
Since 'args-taken? depends on the framework you provide
in the highfun.r I took a liberty to simplify it,
to clearly understand what's going on here.
arg-count?: func [
{How many arguments a function takes?}
f [any-function! word! path!]
args [block!]
/local test
][
test: to-block :f
foreach k args [
append/only test to paren! reduce [:k]
]
test: do/next test
print mold test
(length? args) - (length? second test)
]
For the debugging purpose I also print the output
from the 'do/next executed inside that function.
Running it on the same example as before
arg-count? :do [x 99 sine 4]
[3 [(99) (sine) (4)]]
== 1
clearly shows where the 'do/next stopped executing.
The result from 'arg-count? is 1 - as expected.
Just to confirm, here is another test:
arg-count? :+ [1 2 sine 4]
[3 [(sine) (4)]]
== 2
Take care,
Jan