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 at r-project.org> on behalf of Sorkin, John
<jsorkin at 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 at r-project.org> on behalf of Richard
O'Keefe <raoknz at 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 at 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 at 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 at petzel.at>
> > *Sent:* Monday, January 9, 2023 9:18 PM
> > *To:* akshay kulkarni <akshay_e4 at hotmail.com>
> > *Cc:* R help Mailing list <r-help at 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 at 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 at 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 at 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 at 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 at 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.