From p.dalgaard at biostat.ku.dk  Mon Jun 28 13:52:05 2004
From: p.dalgaard at biostat.ku.dk (Peter Dalgaard)
Date: Mon Jun 28 13:53:00 2004
Subject: [Rd] Problem with hasArg and the ... argument (PR#7027)
In-Reply-To: <20040628091228.B04B8EAD6@slim.kubism.ku.dk>
References: <20040628091228.B04B8EAD6@slim.kubism.ku.dk>
Message-ID: <x2d63jdhne.fsf@biostat.ku.dk>

j.j.goeman@lumc.nl writes:

> xory <- function(x, ...) if (hasArg(y)) y else x
> 
> then 
> 
> x <- 1:10
> xx <- xory(x)
> plot(x, xx)
> 
> works fine, but
> 
> plot(x, xory(x))
> 
> gives the same error. The problem is that the plot function also has
> an argument y, which somehow interferes with the hasArg function. Is
> there an alternative to hasArg that really checks if an argument y
> was supplied for the xy function itself?

No, but hasArg has issues: 

    fnames <- names(formals(sys.function(1)))

is getting the names of plot() rather than xory(). I almost thought I
had caught the Mighty John blundering there, but this actually looks
more like sys.function is not behaving as documented and counts frames
in the wrong direction. 

Checking... Yep, the logic in R_sysfunction() is to give the function
of frame #n:

    if (n > 0)
        n = framedepth(cptr) - n;
    else
        n = - n;
    if (n < 0 )
        errorcall(R_GlobalContext->call, "illegal frame number");
    while (cptr->nextcontext != NULL) {
        if (cptr->callflag & CTXT_FUNCTION ) {
            if (n == 0)
                return duplicate(cptr->callfun);  /***** do we need to DUP? */
            else
                n--;
        }
        cptr = cptr->nextcontext;
    }


whereas the documentation has

     'sys.function' gives the definition of the function currently
     being evaluated in the frame 'n' generations back.

However, we're using the current convention in quite a few places
(sys.function(sys.parent())) and, worse, who know what packages might
do. It is tempting just to change the documentation, but it is part of
a grouped documentation of sys.whatever, which has

   which: the frame number if non-negative, the number of generations
          to go back if negative. (See the Details section.)

       n: the number of frame generations to go back.

and sys.function is documented with argument 'n', which we'd have to
change to 'which', but the default is n=0 for "current function" which
is unlike 'which' which has 0 meaning .GlobalEnv. Argh...

My take is that we need to fix sys.function to behave according to
docs, change what we can in the R internals, and face the consequences
for package maintainers.

-- 
   O__  ---- Peter Dalgaard             Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics     2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark      Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk)             FAX: (+45) 35327907


[Rd] Problem with hasArg and the ... argument (PR#7027)
Peter Dalgaard