# [R] Question about function scope

Sebastien Bihorel @eb@@t|en@b|hore| @end|ng |rom cogn|gencorp@com
Tue Oct 30 21:25:12 CET 2018

```Thanks a lot Eric,

I think you are on the same page as Duncan (at least with his 2nd option). I will definitively explore this.

From: "Eric Berger" <ericjberger using gmail.com>
To: "Duncan Murdoch" <murdoch.duncan using gmail.com>
Cc: "Sebastien Bihorel" <sebastien.bihorel using cognigencorp.com>, "R mailing list" <r-help using r-project.org>
Sent: Tuesday, October 30, 2018 4:17:30 PM
Subject: Re: [R] Question about function scope

Hi Sebastien,
I like Duncan's response. An alternative approach is to pass around environments, as in the following:

bar1 <- function(e) {
e\$x <- e\$y <- e\$z <- 1
cat(sprintf('bar1: x=%d, y=%d, z=%d\n', e\$x, e\$y, e\$z))
}
bar2 <- function(e) {
e\$x <- e\$y <- e\$z <- 2
cat(sprintf('bar2: x=%d, y=%d, z=%d\n', e\$x, e\$y, e\$z))
}

foo <- function(a=1, b=2, c=0, e){
# some setup code
dummy <- a + b
e\$x <- e\$y <- e\$z <- 0
# here is my scope problem
if (c==1) bar1(e)
if (c==2) bar2(e)
# some more code
cat(sprintf('foo: x=%d, y=%d, z=%d\n', e\$x, e\$y, e\$z))
}

e <- new.env()
e\$x <- NA
e\$y <- NA
e\$z <- NA

foo(c=0,e=e)
foo(c=1,e=e)
foo(c=2,e=e)

HTH,
Eric

On Tue, Oct 30, 2018 at 10:13 PM Duncan Murdoch < [ mailto:murdoch.duncan using gmail.com | murdoch.duncan using gmail.com ] > wrote:

On 30/10/2018 3:56 PM, Sebastien Bihorel wrote:
> Hi,
>
> From the R user manual, I have a basic understanding of the scope of function evaluation but have a harder time understanding how to mess with environments.
>
> My problem can be summarized by the code shown at the bottom:
> - the foo function performs some steps including the assignment of default values to 3 objects: x, y, z
> - at some point, I would like to call either the bar1 or bar2 function based upon the value of the c argument of the foo function. These functions assign different values to the x, y, z variables.
> - then foo should move on and do other cool stuff
>
> Based upon default R scoping, the x, y, and z variables inside the bar1 and bar2 functions are not in the same environment as the x, y, and z variables created inside the foo function.
>
> Can I modify the scope of evaluation of bar1 and bar2 so that x, y, and z created inside the foo function are modified?
>
> PS:
> - I know about "<<-" but, in my real code (which I cannot share, sorry), foo is already called within other functions and x, y, and z variables do not exist in the top-level environment and are not returned by foo. So "<<-" does not work (per manual: " Only when <<- has been used in a function that was returned as the value of another function will the special behavior described here occur. ")

I haven't looked up that quote, but it is likely describing a situation
that isn't relevant to you. For you, the important part is that bar1
and bar2 must be created within foo. They don't need to be returned
from it.

So my edit below of your code should do what you want.

foo <- function(a=1, b=2, c=0){

bar1 <- function(){
x <<- 1
y <<- 1
z <<- 1
cat(sprintf('bar1: x=%d, y=%d, z=%d\n', x, y, z))
}

bar2 <- function(){
x <<- 2
y <<- 2
z <<- 2
cat(sprintf('bar2: x=%d, y=%d, z=%d\n', x, y, z))
}

# some setup code
dummy <- a + b
x <- y <- z <- 0

# here is my scope problem
if (c==1) bar1()
if (c==2) bar2()

# some more code
cat(sprintf('foo: x=%d, y=%d, z=%d\n', x, y, z))

}

foo(c=0)
foo(c=1)
foo(c=2)

I get this output:

> foo(c=0)
foo: x=0, y=0, z=0
> foo(c=1)
bar1: x=1, y=1, z=1
foo: x=1, y=1, z=1
> foo(c=2)
bar2: x=2, y=2, z=2
foo: x=2, y=2, z=2

Duncan Murdoch

______________________________________________
[ mailto:R-help using r-project.org | R-help using r-project.org ] mailing list -- To UNSUBSCRIBE and more, see
[ https://stat.ethz.ch/mailman/listinfo/r-help | https://stat.ethz.ch/mailman/listinfo/r-help ]