It has to be stressed that
`*`
and
"*"
by themselves are two different objects: the former is a function, while the latter is just a character vector. Whether using one or the other makes any difference, it depends on the use case. Since in most cases when you pass a function to another function, usually match.fun
is invoked (and this happens to *apply
, do.call
and basically any base function that accepts functions as arguments), passing either object does not make any difference. However, if you use some function from external packages or other sources, you cannot be sure that a call to match.fun
is performed. For example, say that you have this function:
ex_fun<-function(a, b, FUN) {
return(FUN(a, b))
}
This works:
ex_fun(1, 3, `*`)
#[1] 3
This does not:
ex_fun(1, 3, "*")
#Error in FUN(a, b) : could not find function "FUN"
Other point: everything in R is a function, even assignment. So when you use something like:
var <- value
The above instruction is transformed by the parser as:
`<-`(var, value)
In this function, the parser allows var
to be quoted, as for documentation, so this syntax is valid:
"foo" <- 3 * 3
foo
#[1] 9
But as before, foo
and "foo"
remain different objects.
Another implicit usage of match.fun
happens when a function is invoked. When we treat a symbol like a function, the evaluation of an expression looks for a function and not for a generic object. For instance:
a <- 4
a(2)
#Error in a(2) : could not find function "a"
The error message is clear: it's not due to the fact that a
is not a function object, but by the fact that an object of mode function named a
does not exists. For instance, we can declare objects named like base functions and still the parser will call the function when an invocation is made:
log <- 7
log(2)
#[1] 0.6931472
log
#[1] 7
When the parser understands that we are calling a function, it calls match.fun
. This works:
"*"(3, 4)
#[1] 12
This does not, of course:
FUN <- "*"
FUN(3, 4)
#Error in FUN(3, 4) : could not find function "FUN"