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-boun...@r-project.org> on behalf of Richard O'Keefe <rao...@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 <valen...@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...@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 <valen...@petzel.at> > > *Sent:* Monday, January 9, 2023 9:18 PM > > *To:* akshay kulkarni <akshay...@hotmail.com> > > *Cc:* R help Mailing list <r-help@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...@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@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%7C7667e3a25e004319a09408daf751c352%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094227808126030%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=DYZ1Jle5re1jwM%2F1pVrpS%2BwOeT%2BgjNXQZz0Fq8N4sIU%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%7C7667e3a25e004319a09408daf751c352%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094227808126030%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=q1Gy%2FTQd0eXsa8fUKW3slt%2Byn7EUfqmOOqPGDoxYx4U%3D&reserved=0 > >> and provide commented, minimal, self-contained, reproducible code. > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help@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%7C7667e3a25e004319a09408daf751c352%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094227808126030%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=DYZ1Jle5re1jwM%2F1pVrpS%2BwOeT%2BgjNXQZz0Fq8N4sIU%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%7C7667e3a25e004319a09408daf751c352%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094227808126030%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=q1Gy%2FTQd0eXsa8fUKW3slt%2Byn7EUfqmOOqPGDoxYx4U%3D&reserved=0 > and provide commented, minimal, self-contained, reproducible code. > [[alternative HTML version deleted]] ______________________________________________ R-help@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%7C7667e3a25e004319a09408daf751c352%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094227808126030%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=DYZ1Jle5re1jwM%2F1pVrpS%2BwOeT%2BgjNXQZz0Fq8N4sIU%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%7C7667e3a25e004319a09408daf751c352%7C717009a620de461a88940312a395cac9%7C0%7C0%7C638094227808126030%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=q1Gy%2FTQd0eXsa8fUKW3slt%2Byn7EUfqmOOqPGDoxYx4U%3D&reserved=0 and provide commented, minimal, self-contained, reproducible code. ______________________________________________ R-help@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.