Open In App

Dynamic Scoping in R Programming

Improve
Improve
Like Article
Like
Save
Share
Report

R is an open-source programming language that is widely used as a statistical software and data analysis tool. R generally comes with the Command-line interface. R is available across widely used platforms like Windows, Linux, and macOS. Also, the R programming language is the latest cutting-edge tool. The scoping rules for R are the main feature that makes it different from the original S language. R language uses lexical scoping or static scoping. A common alternative is Dynamic scoping.

Concept Behind Dynamic Scoping

Consider the following function:

R




f <- function(x, y)
{
   x^2 + y/z
}


This function has 2 formal arguments x and y. In the body of the function, there is another symbol z. In this case, z is a free variable. The scoping rules of a language determine how values are assigned to free variables. Free variables are not formal arguments and are not local variables (assigned inside the body). Lexical scoping in R means that the values of free variables are searched for in the environment in which the function was defined. Searching for the value of the free variable means:

  • If the value of the symbol is not found in the environment in which a function was defined, then the search is continued in the parent environment.
  • The search continues down the sequence of the parent environment until the users hit the top-level environment; this is usually the global environment (workspace) or the namespace of a package.
  • If the value for a given symbol cannot be found once the empty environment has arrived, then an error is thrown. The value for the free variable is given in the below image.
Dynamic Scoping in R ProgrammingGeeksforgeeks

Dynamic Scoping in R Programming

Typically a function is defined in the global environment so that the value of free variables is just found in the user’s workspace however in R one can have functions defined inside other functions. For example, have a look at the below code. 

R




make.power <- function(n){
  pow <- function(x){
    x = x^n
  }
  pow
}
 
cube <- make.power(3)
square <- make.power(2)
print(cube(3))
print(square(3))


Output

[1] 27
[1] 9

The power function takes the argument x and raised the power n. So that makes the function pow return inside the function value. n is a free variable and is defines in the pow function. What’s in a function environment? 

R




ls(environment(cube))


[1] "n"   "pow"

This code assumes that the R environment has a specified object called a cube. The items in a given environment can be listed using the ls() method. The environment of the cube, which is acquired using the environment() function, is the argument to ls() in this instance.

R




get("n", environment(cube))


[1] 3

The value of n is retrieved from the environment of the cube using the get() function, presuming an object named n is declared within that environment.
 

R




ls(environment(square))


[1] "n"   "pow"

This code expects that the R environment has defined an object called a square. The items in a given environment can be listed using the ls() method. The environment of the square, which was acquired via the environment() function, is the argument to ls() in this instance.

R




get("n", environment(square))


[1] 2

When you type get(“n”, environment(square)), you’re attempting to retrieve the value of n from the square’s environment. Since Square’s environment does not specify n.

Let’s consider another example:

R




y <- 10
 
# creating a function f which takes argument x
f <- function(x){
  # y is free variable
  y <- 2 
   
  # g function is also a free variable
  # not defined in the scope of function
  y^2 + g(x) 
}
 
g <- function(x){
  # y is free variable
  # value of y in this function is 10
  x*y
}


What is the value of y in this case? 

  • With the lexical scoping in R, the value of y in the function g is looked up in the environment in which the function was defined, in this case, the global environment, so the value of y is 10.
  • With the dynamic scoping in R, the value of y is looked up in the environment from which the function was called (sometimes referred to as calling environment).
  • In R the calling environment is known as the parent frame. So the value of y would be 2.

When a function is defined in the global environment and is subsequently called from the global environment, then the defining environment and the calling environment are the same. This can sometimes give the appearance of dynamic scoping. 

R




g <- function(x){
  a <- 3
  # in this case x is function a formal argument and
  # a is local variable and
  # y is free variable
  x + a + y
}
 
# printing value of g(2)
print(g(2))


If we call g(2) it will give an error like the following:

Output

Error in g(2) : object 'y' not found

After assigning value to y call g(2) as follows: 

R




g <- function(x){
  a <- 3
  x + a + y
}
 
# assigning value to y
y <- 3
 
# print g(2)
print(g(2))


Output

[1] 8


Last Updated : 18 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads