I'm not sure what you mean by this code "working":
`f= outer (x, y, FUN = function(x,y) cos(y) / (1+x^2))`
What this will do is attempt to access a variable named f= outer (x, y, FUN = function(x,y) cos(y) / (1+x^2))
, e.g. I could write:
`f= outer (x, y, FUN = function(x,y) cos(y) / (1+x^2))` = 3
`f= outer (x, y, FUN = function(x,y) cos(y) / (1+x^2))`
# [1] 3
This is an insanely confusing thing to do, but surrounding objects in backticks (`
) allows you to declare arbitrarily-named objects.
Again, don't do this unless you absolutely know what you're doing (i.e. well past your first day of R programming).
Anyway, regarding why *
needs quotation marks, it's because *
is an operator. Everything in R is a function (almost), but operators are special functions in that they let you write them from left to right like:
variable1 operator variable2
instead of the normal
function(variable1, variable2)
That said, all operators also have a functional form; but, to distinguish the functional form from the operator form, the R parser needs them to be set apart with quotes (or with backticks); the following are the same:
3 * 4
'*'(3, 4)
"*"(3, 4) #single and double quotes in R are basically the same
`*`(3, 4)
the FUN
argument of outer
requires functions, not operators, so we have to serve *
in its functional form, e.g. "*"
.
One more bit of detail -- you can observe R internally changing the operator form into the functional form as part of the code-parsing process (i.e., before evaluation, R will already convert the operator form into functional form):
as.character(substitute(3 * 4))
# [1] "*" "3" "4"
# alternatively
pryr::ast(3 * 4)
# \- ()
# \- `*
# \- 3
# \- 4