Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding functions with variable scoping

Tags:

r

scoping

For this code :

A <- 100; B <- 20

f1 <- function(a) {
  B <- 100
  f2 <- function(b) {
    A <<- 200
    B <<- 1000
  }
  f2(a)
}

f1(B)
cat(A)
cat(B)

The following is the output :

> cat(A)
200
> cat(B)
20

Here is my understanding of above code : The function f1 is invoked with parameter B that has value 20. Within f1 a local variable B is created ( B <- 100 ), f1.B does not have an effect on the variable B initialiazed outside function call f1 as f1.B is locally scoped to the function f1. A new function f2 is created within f1 that accepts a single argument b. Within f1 the function f2 is invoked passing as paramter a to f2. f2 does not makes use of its argument b. f2 modifies A using the global operator <-- and sets it to 200. This why cat(A) outputs 200.

My understanding is incorrect as B is set to 20 when I expect 1000 ? As A is set to 200 in f2 using <-- . d should same not also occur for B ?

like image 595
blue-sky Avatar asked Dec 07 '17 09:12

blue-sky


1 Answers

The function f1 is invoked with parameter B that has value 20.

No, I don't think so. It is invoked with a parameter a that has the same value as the B in the global environment. B is not directly involved in this point.

You then assign a 100 to a different B, which you call f1.B in your post. (Note that, following the previous statement, that B is created here, not overwritten.)

Then when using the <<- operator, it traverses up in scope, going from f2 (where no B exists) to f1, where it finds this "f1.B" and assigns a 1000.

Similarly, when using the <<- on A, it traverses up. It finds no A in either f2 or f1, but does in the global environment and assigns it there.

You then print to old original B, which has never been altered.

From the help:

<<- and ->> (...) cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment.

So for B, "such a variable is found", while for A "assignment takes place in the global environment."

Conclusion: <<- is confusing, and often better to be avoided.

like image 97
Axeman Avatar answered Oct 28 '22 15:10

Axeman