Search code examples
rlexical-scope

Lexical scoping and the <<- operator in R


This code appears in the Intro to R manual.

open.account <- function(total) {
    list(deposit = function(amount) {
        if (amount <= 0) stop("Deposits must be positive!\n")
        total <<- total + amount
        cat(amount, "deposited.  Your balance is", total, "\n\n")
    }, withdraw = function(amount) {
        if (amount > total) stop("You don’t have that much money!\n")
        total <<- total - amount
        cat(amount, "withdrawn.  Your balance is", total, "\n\n")
    }, balance = function() {
        cat("Your balance is", total, "\n\n")
    })
}

This is supposed to simulate how the bank account works, keeping track of the running balance while accounting for deposits and withdrawals. In order to do this, the program needs to look at the balance before each transaction, which is dynamic, and therefore can't be defined with the function. This is where I'm a little fuzzy...

My question is specifically about the <<- operator, which allows the function to index the value of total outside of the environment.

The rules of lexical scoping dictate that the value of variables or objects are determined in the environment in which they were defined. This determines where r should look, not when.

That being said, when we use the <<- operator to point to a value outside the current environment, where is it pointing? This is a conceptual question that is stopping me from fully grasping how it works. I understand how the code works, but I'm not sure where the value is being pulled from when we use the <<- operator.


Solution

  • The operators ‘<<-’ and ‘->>’ are normally only used in functions, and cause a search to 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

    variable at the global level

    z <- 10
    

    Does not modify the global value of z

    myfun <- function(x){
     z <- x
    print(z)
    }
    

    modify the value of z inside the myfun but don't modify z at the global level.

        myfun0 <- function(x){
         z <- x
           myfun1 <- function(y){
             z <<- (y+1)
    }
    
      myfun1(x)
        print(z)
             }
    

    Modify the z in the global environment

    myfunG <- function(x){
    z <<- x
    print(" z in the global envronment is modified")
    }
    

    see this post as well.