What are closures in the R language?

Closures are a powerful concept used to create functions between other functions in the R language. This concept helps when we change or repeat one function in the same code and dataset. It also allows a function to retain access to its surrounding environment's variables even after executing the outer function. It enables the function to “close over” or “encapsulate” the variables it needs, creating a self-contained unit of behavior.

In R, closures are often used when we need to create functions with some internal state or configuration, but we don’t want to expose that state to the global environment. Closures are created when we define a function within another function.

Visual representation of a closure
Visual representation of a closure

Key points

  • A closure consists of a function and the environment in which it was created. The environment contains the local variables and their values.

  • It encapsulates their state and behavior, which can’t be directly accessed or modified outside the function.

  • It uses lexical scoping, which means that functions look up variable values in the environment where they were defined, not where they’re called. This is how closures retain access to their parent function’s variables.

  • The <<- operator is used to assign a value to a variable in a higher-level (parent) environment. 

Example

Here’s an example of a closure to better understand the concept:

# Create a function with name counter to define the closure concept
counter <- function() {
count <- 0
# Create another function with name increment in the counter function
increment <- function() {
count <<- count + 1
cat("Increment the count:", count, "\n")
}
# Return the value
return(increment)
}
# Call function and store value in the variable
counter1 <- counter()
counter2 <- counter()
counter1() # Output: Count: 1
counter2() # Output: Count: 1
counter1() # Output: Count: 2
counter2() # Output: Count: 2
counter2() # Output: Count: 3
counter1() # Output: Count: 3

Explanation

  • Line 2: This creates a function with the name counter which holds the property of the closure.

  • Line 3: The count variable is enclosed within the scope of the counter function.

  • Lines 4–8: This creates another function in the counter function with the name increment. This function still has access to the count variable even after counter has finished executing. Here we use the <<- operator to store the value in the variable.

  • Line 10: This returns the function.

  • Lines 14–15: This calls the counter() function and stores its value in two different variables.

  • Lines 17–22: This calls the function where we store the values of the function above to display the output. It allows us to create multiple instances of the counter closure, each with its own independent count.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved