Hello,

I agree the documentation of args can be improved, but the main question is 
what the return should be.
I guess the reason args() returns NULL is because of the way argument-matching 
works for primitives: there is a lot going on under the hood, and what 
arguments are/are not acceptable for `[` can't be stated as straightforward as 
we can with other functions.
Note also the difference in printing "sum" and "[": sum first prints 
"function(..., na.rm=FALSE)", whereas `[` jumps straight to the body. And this 
is not an artefact of printing it, as makes overwriting it makes clear: 
`[` <- function(x, i, j, ..., drop=FALSE) .Primitive("[")
exhibited very strange behaviour, where you need to call it twice/nested: 1[2] 
returns a primitive function, to get it to do its job you need 1[2](df, 3, 4) 
instead of df[3,4].
So general advice would probably be to stay away from messing with arguments 
with primitives, as ?args already hints at: " mainly used interactively (...). 
For programming, consider using formals instead." 
Basically, primitives are optimized and down to the core, which probably means 
the concept of an argument-list may not be as clear as it is with "normal" 
functions.
So working with args() on primitives comes with some risks, which probably is 
the reason that formals() always return NULL in that case. 
What is your use case?
If you really need a return value, I think you could catch NULL-values, 
something like this:
args <- function(name) {
  if(is.character(name)) name <- get(name, parent.frame(), mode='function')
  if(!is.function(name)) return(NULL)
  ret <- base::args(name)
  if(is.null(ret) && is.primitive(name)) {
    ret <- function(...) NULL
    environment(ret) <- parent.frame()
  }
  return(ret)
}

Which would just return "function(...) NULL" for args("["), which is of the 
expected class, but does not give you any real information. Would that help you?
Otherwise, to get to know the arguments there is of course "?"
And note that if there is a dispatch, it's possible to get the argument-list of 
a specific method, e.g. args(`[.data.frame`) works as expected (as it is not a 
primitive) 


Best regards, 
Emil Bode

On 07/10/2018, 16:34, "R-devel on behalf of Rui Barradas" 
<r-devel-boun...@r-project.org on behalf of ruipbarra...@sapo.pt> wrote:

    Hello,
    
    This is because args(`[`) returns NULL and class(NULL) is NULL.
    So the question would be why is the return value of args(`[`) NULL?
    
    Rui Barradas
    
    Às 15:14 de 07/10/2018, Peter Dalgaard escreveu:
    > 
    > 
    >> On 7 Oct 2018, at 16:04 , Rui Barradas <ruipbarra...@sapo.pt> wrote:
    >>
    >> Hello,
    >>
    >> I don't see why you say that the documentation seems to be wrong:
    >>
    >>
    >> class(args(`+`))
    >> #[1] "function"
    >>
    >>
    >> args() on a primitive does return a closure. At least in this case it 
does.
    > 
    > But in this case it doesn't:
    > 
    >> is.primitive(get("["))
    > [1] TRUE
    >> class(args(get("[")))
    > [1] "NULL"
    > 
    > Or, for that matter:
    > 
    >> is.primitive(`[`)
    > [1] TRUE
    >> class(args(`[`))
    > [1] "NULL"
    > 
    > -pd
    > 
    >>
    >>
    >> Rui Barradas
    >>
    >> Às 14:05 de 07/10/2018, Peter Dalgaard escreveu:
    >>> There is more "fun" afoot here, but I don't recall what the point may 
be:
    >>>> args(get("+"))
    >>> function (e1, e2)
    >>> NULL
    >>>> args(get("["))
    >>> NULL
    >>>> get("[")
    >>> .Primitive("[")
    >>>> get("+")
    >>> function (e1, e2)  .Primitive("+")
    >>> The other index operators, "[[", "[<-", "[[<-" are similar
    >>> The docs are pretty clear that args() on a primitive should yield a 
closure, so at least the documentation seems to be wrong.
    >>> -pd
    >>>> On 6 Oct 2018, at 19:26 , Laurent Gautier <lgaut...@gmail.com> wrote:
    >>>>
    >>>> Hi,
    >>>>
    >>>> A short code example showing the warning might the only thing needed 
here:
    >>>>
    >>>> ```
    >>>>> formals(args(`[`))
    >>>> NULL
    >>>>
    >>>> *Warning message:In formals(fun) : argument is not a function*
    >>>>> is.function(`[`)
    >>>> [1] TRUE
    >>>>> is.primitive(`[`)
    >>>> [1] TRUE
    >>>> ```
    >>>>
    >>>> Now with an other primitive:
    >>>>
    >>>> ```
    >>>>> formals(args(`sum`))
    >>>> $...
    >>>>
    >>>>
    >>>> $na.rm
    >>>> [1] FALSE
    >>>>
    >>>>> is.function(`sum`)
    >>>> [1] TRUE
    >>>>> is.primitive(`sum`)
    >>>> [1] TRUE
    >>>>> class(`[`)
    >>>> [1] "function"
    >>>> ```
    >>>>
    >>>> Is this a feature ?
    >>>>
    >>>>
    >>>> Laurent
    >>>>
    >>>>        [[alternative HTML version deleted]]
    >>>>
    >>>> ______________________________________________
    >>>> R-devel@r-project.org mailing list
    >>>> https://stat.ethz.ch/mailman/listinfo/r-devel
    >
    
    ______________________________________________
    R-devel@r-project.org mailing list
    https://stat.ethz.ch/mailman/listinfo/r-devel
    

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to