Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the '->' operator in R to define a function requires parentheses to work

Tags:

syntax

r

I was playing with R and its assignment operators a little and I found out that if I want to use the -> operator to write a function into a variable, I need to enclose the definition inside parentheses like so:

(function(x) {
return(x)
}) -> my_func

my_func("hi")

The following doesn't work as expected:

function(x) {
    return(x)
} -> my_func

my_func("hi")

The output seems also rather strange to me:

function (x)  my_func <- {
    return(x) }

Error in eval(expr, envir, enclos): could not find function "my_func" Traceback:

Does anyone know why that is? My guess is that it will have something to do with the precedence and associativity of operators, but I can't put my finger on it...

like image 726
martin-is-my-name Avatar asked Jan 30 '23 15:01

martin-is-my-name


1 Answers

The documentation for "function" in R show the following usage

function( arglist ) expr

So basically everything after function() will be interpreted as an expression and used as the function body. It just so happens that the assignment operator can be interpreted as part of that expression. Note that this is a valid expression in R

{1 - 2} -> x

So you are basically defining a function that does the assignment. You are not creating by evaluating that statement -- only defining an unnamed function. So for your example

function(x) {
    x
} -> my_func

This line nerver creates a variable named my_func. It creates a function that will assign to a variable named my_func but that variable will only exist in the function scope and will not be available after the function finished running.

In your actual example, you used return so that local variable will never actually be created because the return() happens in the code block before the assignment completes. But if you did a global assignment, that would be more clear

if (exists("my_func")) rm(my_func)
exists("my_func")
# [1] FALSE
f <- function(x) {
    x
} ->> my_func
f(5)
exists("my_func")
# [1] TRUE

But you can see that if you run, that variable is never created

if (exists("my_func")) rm(my_func)
function(x) {
    x
} -> my_func
exists("my_func")
# [1] FALSE

When you use x <- function() {} with a new line after, these is a clear break so the parser knows where the expression ends. Adding in the () also makes is clear to the parse where the function expression ends so R doesn't gobble the assignment into the expression (function body) as well. Functions in R don't require curly braces or explicit return() calls: function(x) x is a valid function definition.

like image 125
MrFlick Avatar answered Feb 01 '23 07:02

MrFlick