Reputation: 938
Why the following nested function f2
doesn't work as expected?
c = 2
f1 = function(a,b){
(a+b)*c
}
f1(1,2) # 6
f2 = function(a,b,c){
f1(a,b)
}
f2(1,2,c=3) # still 6, expect 9
Update
I found the following modification works:
f2 = function(a,b,c){
c <<- c
f1(a,b)
}
f2(1,2,c=3) # returns 9 as expected
But I am confused about the how a function call searches values along the path of environments. If my problem is just due to R's lazy evaluation, I just need c <- c
. Then the new c
will be in the environment where f2
is called. Since f1
is nested in f2
, its environment is nested in that of f2
. So when I need c
in f1
, it should be able to find c
in the parent environment. However, it turns out that it can only find the global c
, not the c
in f2
's environment.
Upvotes: 1
Views: 3252
Reputation: 306
R has lexical scope; a variable that is not assigned in a function is resolved against its static environment. In your case, f1 sees the value of c in your global environment, which is 2. Within f2, c == 3 because it is passed as an argument which masks the global c, but when f1 is called, it still sees c==2 from its enclosing environment. You expected dynamic scoping, where c would take the value of its runtime environment (i.e., within f2). You can set c <- 3 outside the functions, before f2, or you can do this to copy the local value passed as 'c' in f2 to the global environment:
f2 = function(a,b,c){
c <<- c # local argument c copied to global c
f1(a,b)
}
more discussion of lexical scope in R: https://darrenjw.wordpress.com/2011/11/23/lexical-scope-and-function-closures-in-r/
Upvotes: 5