Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In R, is it possible to define a function using `function`? [duplicate]

Tags:

r

I am trying to call the function `function` to define a function in R code.

As we all know™️, `function`is a .Primitive that’s used internally by R to define functions when the user uses the conventional syntax, i.e.

mean1 = function (x, ...) base::mean(x, ...)

But there’s nothing preventing me from calling that primitive directly. Or so I thought. I can call other primitives directly (and even redefine them; for instance, in a moment of madness I overrode R’s builtin `for`). So this is in principle possible.

Yet I cannot get it to work for `function`. Here’s what I tried:

# Works
mean2 = as.function(c(formals(mean), quote(mean(x, ...))))

# Works
mean3 = eval(call('function', formals(mean), quote(mean(x, ...))))

# Error: invalid formal argument list for "function"
mean4 = `function`(formals(mean), quote(mean(x, ...)))

The fact that mean3 in particular works indicates to me that mean4 should work. But it doesn’t. Why?

I checked the definition of the `function` primitive in the R source. do_function is defined in eval.c. And I see that it calls CheckFormals, which ensures that each argument is a symbol, and this fails. But why does it check this, and what does that mean?

And most importantly: Is there a way of calling the `function` primitive directly?


Just to clarify: There are trivial workarounds (this question lists two, and there’s at least a third). But I’d like to understand how this (does not) works.

like image 952
Konrad Rudolph Avatar asked Nov 17 '22 22:11

Konrad Rudolph


1 Answers

This is because function is a special primitive:

typeof(`function`)
#> [1] "special"

The arguments are not evaluated, so you have actually passed quote(formals(mean)) instead of the value of formals(mean). I don't think there's a way of calling function directly without evaluation tricks, except with an empty formals list which is just NULL.

like image 151
Lionel Henry Avatar answered Jan 03 '23 15:01

Lionel Henry