[R] return value of {....}

Bert Gunter bgunter@4567 @end|ng |rom gm@||@com
Mon Jan 16 02:49:52 CET 2023


Sorry, John. If I understand you correctly, R has no "Global
Variables" in the sense that you seem to indicate. It does have a
"Global environment", but variables referred to in a function but not
found in the function environment are *not* necessarily searched for
in the "Global Environment" -- they are searched for in the function's
enclosing (defining) environment, then in that environment's enclosing
environment if not found there, etc.

Consider:
f <- f <- function(){
   x <- 3
   g <- function() x  ## x not bound to a value in g's environment
   g ## f returns the function g
}
> environment()
<environment: R_GlobalEnv>
x <- 5 ## defined in the Global environment
g <- f()
## Now what do you think g() returns?

If I have misconstrued what you said, my apologies.
Even if I have not, none of the above is revelatory -- it's all
standard, documented R behavior.

Cheers,
Bert

Cheers,
Bert



while something like d$something <- ... may seem like you're directly
modifying the data it does not actually do so. Most R objects try to
be immutable, that is, the object may not change after creation. This
guarantees that if you have a binding for same object the object won't
change sneakily.

There is a data structure that is in fact mutable which are
environments. For example compare

L <- list()
local({L$a <- 3})
L$a

with

E <- new.env()
local({E$a <- 3})
E$

Valentin Petzel valentin using petzel.at via r-project.org

2:25 AM (5 hours ago)


to avi.e.gross, R-help

On Sun, Jan 15, 2023 at 5:07 PM Sorkin, John <jsorkin using som.umaryland.edu> wrote:
>
> Richard,
> I sent my prior email too quickly:
>
> A slight addition to your code shows an important aspect of R, local vs. global variables:
>
> x <- 137
> f <- function () {
>        a <- x
>        x <- 42
>        b <- x
>        list(a=a, b=b)
>    }
>  f()
> print(x)
>
> When run the program produces the following:
>
> > x <- 137
> > f <- function () {
> +        a <- x
> +        x <- 42
> +        b <- x
> +        list(a=a, b=b)
> +    }
> >  f()
> $a
> [1] 137
>
> $b
> [1] 42
>
> > print(x)
> [1] 137
>
> The fist x, a <- x, invokes an x variable that is GLOBAL. It is known both inside and outside the function.
> The second x, x <- 42, defines an x that is LOCAL to the function, it is not known to the program that called the function. The LOCAL value of x is used in the expression  b <- x. As can be seen by the print(x) statement, the LOCAL value of x is NOT known by the program that calls the function. The class of a variable, scoping (i.e. local vs. variable) can be a source of subtle programming errors. A general recommendation is to AVOID use of a global variable in a function, i.e. don't use a variable in function that is not passed as a parameter to the function (as was done in the function above in the statment a <- x). If you need to use a variable in a function that is known by the program that calls the function, pass the variable as a argument to the function e.g.
>
> Use this code:
>
> # Set values needed by function
> y <- 2
> b <- 30
>
> myfunction <- function(a,b){
> cat("a=",a,"b=",b,"\n")
>   y <- a
>   y2 <- y+b
>   cat("y=",y,"y2=",y2,"\n")
> }
> # Call the function and pass all needed values to the function
> myfunction(y,b)
>
> Don't use the following code that depends on a global value that is known to the function, but not passed as a parameter to the function:
>
> y <- 2
> myNGfunction <- function(a){
>   cat("a=",a,"b=",b,"\n")
>   y <- a
>   y2 <- y+b
>   cat("y=",y,"y2=",y2,"\n")
> }
> # b is a global variable and will be know to the function,
> # but should be passed as a parameter as in example above.
> b <- 100
> myNGfunction(y)
>
> John
>
> ________________________________________
> From: R-help <r-help-bounces using r-project.org> on behalf of Sorkin, John <jsorkin using som.umaryland.edu>
> Sent: Sunday, January 15, 2023 7:40 PM
> To: Richard O'Keefe; Valentin Petzel
> Cc: R help Mailing list
> Subject: Re: [R] return value of {....}
>
> Richard,
> A slight addition to your code shows an important aspect of R, local vs. global variables:
>
> x <- 137
> f <- function () {
>        a <- x
>        x <- 42
>        b <- x
>        list(a=a, b=b)
>    }
>  f()
> print(x)
>
> ________________________________________
> From: R-help <r-help-bounces using r-project.org> on behalf of Richard O'Keefe <raoknz using gmail.com>
> Sent: Sunday, January 15, 2023 6:39 PM
> To: Valentin Petzel
> Cc: R help Mailing list
> Subject: Re: [R] return value of {....}
>
> I wonder if the real confusino is not R's scope rules?
> (begin .) is not Lisp, it's Scheme (a major Lisp dialect),
> and in Scheme, (begin (define x ...) (define y ...) ...)
> declares variables x and y that are local to the (begin ...)
> form, just like Algol 68.  That's weirdness 1.  Javascript
> had a similar weirdness, when the ECMAscript process eventually
> addressed.  But the real weirdness in R is not just that the
> existence of variables is indifferent to the presence of curly
> braces, it's that it's *dynamic*.  In
> f <- function (...) {
>    ... use x ...
>    x <- ...
>    ... use x ...
> }
> the two occurrences of "use x" refer to DIFFERENT variables.
> The first occurrence refers to the x that exists outside the
> function.  It has to: the local variable does not exist yet.
> The assignment *creates* the variable, so the second
> occurrence of "use x" refers to the inner variable.
> Here's an actual example.
> > x <- 137
> > f <- function () {
> +     a <- x
> +     x <- 42
> +     b <- x
> +     list(a=a, b=b)
> + }
> > f()
> $a
> [1] 137
> $b
> [1] 42
>
> Many years ago I set out to write a compiler for R, and this was
> the issue that finally sank my attempt.  It's not whether the
> occurrence of "use x" is *lexically* before the creation of x.
> It's when the assignment is *executed* that makes the difference.
> Different paths of execution through a function may result in it
> arriving at its return point with different sets of local variables.
> R is the only language I routinely use that does this.
>
> So rule 1: whether an identifier in an R function refers to an
> outer variable or a local variable depends on whether an assignment
> creating that local variable has been executed yet.
> And rule 2: the scope of a local variable is the whole function.
>
> If the following transcript not only makes sense to you, but is
> exactly what you expect, congratulations, you understand local
> variables in R.
>
> > x <- 0
> > g <- function () {
> +     n <- 10
> +     r <- numeric(n)
> +     for (i in 1:n) {
> +         if (i == 6) x <- 100
> +         r[i] <- x + i
> +     }
> +     r
> + }
> > g()
>  [1]   1   2   3   4   5 106 107 108 109 110
>
>
> On Fri, 13 Jan 2023 at 23:28, Valentin Petzel <valentin using petzel.at> wrote:
>
> > Hello Akshay,
> >
> > R is quite inspired by LISP, where this is a common thing. It is not in
> > fact that {...} returned something, rather any expression evalulates to
> > some value, and for a compound statement that is the last evaluated
> > expression.
> >
> > {...} might be seen as similar to LISPs (begin ...).
> >
> > Now this is a very different thing compared to {...} in something like C,
> > even if it looks or behaves similarly. But in R {...} is in fact an
> > expression and thus has evaluate to some value. This also comes with some
> > nice benefits.
> >
> > You do not need to use {...} for anything that is a single statement. But
> > you can in each possible place use {...} to turn multiple statements into
> > one.
> >
> > Now think about a statement like this
> >
> > f <- function(n) {
> > x <- runif(n)
> > x**2
> > }
> >
> > Then we can do
> >
> > y <- f(10)
> >
> > Now, you suggested way would look like this:
> >
> > f <- function(n) {
> > x <- runif(n)
> > y <- x**2
> > }
> >
> > And we'd need to do something like:
> >
> > f(10)
> > y <- somehow_get_last_env_of_f$y
> >
> > So having a compound statement evaluate to a value clearly has a benefit.
> >
> > Best Regards,
> > Valentin
> >
> > 09.01.2023 18:05:58 akshay kulkarni <akshay_e4 using hotmail.com>:
> >
> > > Dear Valentin,
> > >                           But why should {....} "return" a value? It
> > could just as well evaluate all the expressions and store the resulting
> > objects in whatever environment the interpreter chooses, and then it would
> > be left to the user to manipulate any object he chooses. Don't you think
> > returning the last, or any value, is redundant? We are living in the
> > 21st century world, and the R-core team might,I suppose, have a definite
> > reason for"returning" the last value. Any comments?
> > >
> > > Thanking you,
> > > Yours sincerely,
> > > AKSHAY M KULKARNI
> > >
> > > ----------------------------------------
> > > *From:* Valentin Petzel <valentin using petzel.at>
> > > *Sent:* Monday, January 9, 2023 9:18 PM
> > > *To:* akshay kulkarni <akshay_e4 using hotmail.com>
> > > *Cc:* R help Mailing list <r-help using r-project.org>
> > > *Subject:* Re: [R] return value of {....}
> > >
> > > Hello Akshai,
> > >
> > > I think you are confusing {...} with local({...}). This one will
> > evaluate the expression in a separate environment, returning the last
> > expression.
> > >
> > > {...} simply evaluates multiple expressions as one and returns the
> > result of the last line, but it still evaluates each expression.
> > >
> > > Assignment returns the assigned value, so we can chain assignments like
> > this
> > >
> > > a <- 1 + (b <- 2)
> > >
> > > conveniently.
> > >
> > > So when is {...} useful? Well, anyplace where you want to execute
> > complex stuff in a function argument. E.g. you might do:
> > >
> > > data %>% group_by(x) %>% summarise(y = {if(x[1] > 10) sum(y) else
> > mean(y)})
> > >
> > > Regards,
> > > Valentin Petzel
> > >
> > > 09.01.2023 15:47:53 akshay kulkarni <akshay_e4 using hotmail.com>:
> > >
> > >> Dear members,
> > >>                              I have the following code:
> > >>
> > >>> TB <- {x <- 3;y <- 5}
> > >>> TB
> > >> [1] 5
> > >>
> > >> It is consistent with the documentation: For {, the result of the last
> > expression evaluated. This has the visibility of the last evaluation.
> > >>
> > >> But both x AND y are created, but the "return value" is y. How can this
> > be advantageous for solving practical problems? Specifically, consider the
> > following code:
> > >>
> > >> F <- function(X) {  expr; expr2; { expr5; expr7}; expr8;expr10}
> > >>
> > >> Both expr5 and expr7 are created, and are accessible by the code
> > outside of the nested braces right? But the "return value" of the nested
> > braces is expr7. So doesn't this mean that only expr7 should be accessible?
> > Please help me entangle this (of course the return value of F is expr10,
> > and all the other objects created by the preceding expressions are deleted.
> > But expr5 is not, after the control passes outside of the nested braces!)
> > >>
> > >> Thanking you,
> > >> Yours sincerely,
> > >> AKSHAY M KULKARNI
> > >>
> > >>     [[alternative HTML version deleted]]
> > >>
> > >> ______________________________________________
> > >> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> > >> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fstat.ethz.ch%2Fmailman%2Flistinfo%2Fr-help&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Jp7JGV%2BVKkAx3SI%2Fak%2BiEIkUraGyQBTfSLWqRRUYmaQ%3D&reserved=0
> > >> PLEASE do read the posting guide
> > https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.r-project.org%2Fposting-guide.html&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Got4ab%2BEO6LD%2FOXqp9j9ImnSn0zi8vhV6YZMD7OJ8WU%3D&reserved=0
> > >> and provide commented, minimal, self-contained, reproducible code.
> >
> >         [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fstat.ethz.ch%2Fmailman%2Flistinfo%2Fr-help&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Jp7JGV%2BVKkAx3SI%2Fak%2BiEIkUraGyQBTfSLWqRRUYmaQ%3D&reserved=0
> > PLEASE do read the posting guide
> > https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.r-project.org%2Fposting-guide.html&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Got4ab%2BEO6LD%2FOXqp9j9ImnSn0zi8vhV6YZMD7OJ8WU%3D&reserved=0
> > and provide commented, minimal, self-contained, reproducible code.
> >
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fstat.ethz.ch%2Fmailman%2Flistinfo%2Fr-help&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Jp7JGV%2BVKkAx3SI%2Fak%2BiEIkUraGyQBTfSLWqRRUYmaQ%3D&reserved=0
> PLEASE do read the posting guide https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.r-project.org%2Fposting-guide.html&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Got4ab%2BEO6LD%2FOXqp9j9ImnSn0zi8vhV6YZMD7OJ8WU%3D&reserved=0
> and provide commented, minimal, self-contained, reproducible code.
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fstat.ethz.ch%2Fmailman%2Flistinfo%2Fr-help&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Jp7JGV%2BVKkAx3SI%2Fak%2BiEIkUraGyQBTfSLWqRRUYmaQ%3D&reserved=0
> PLEASE do read the posting guide https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.r-project.org%2Fposting-guide.html&data=05%7C01%7CJSorkin%40som.umaryland.edu%7C75c2bc42c20b4c03601d08daf75a4405%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094264319036570%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=Got4ab%2BEO6LD%2FOXqp9j9ImnSn0zi8vhV6YZMD7OJ8WU%3D&reserved=0
> and provide commented, minimal, self-contained, reproducible code.
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list