Bird
Raised Fist0
R Programmingprogramming~20 mins

Environment and closures in R Programming - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Environment and Closures Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of a closure capturing a variable
What is the output of this R code?
make_counter <- function() {
  count <- 0
  function() {
    count <<- count + 1
    count
  }
}
c <- make_counter()
c()
c()
R Programming
make_counter <- function() {
  count <- 0
  function() {
    count <<- count + 1
    count
  }
}
c <- make_counter()
c()
c()
A
[1] 2
[1] 3
B
[1] 0
[1] 1
C
[1] 1
[1] 1
D
[1] 1
[1] 2
Attempts:
2 left
💡 Hint
Think about how the <<- operator changes the variable in the parent environment.
❓ Predict Output
intermediate
2:00remaining
Value of variable after nested function calls
What is the value of x after running this code?
x <- 5
f <- function() {
  x <- 10
  g <- function() {
    x <<- 20
  }
  g()
  x
}
f()
x
R Programming
x <- 5
f <- function() {
  x <- 10
  g <- function() {
    x <<- 20
  }
  g()
  x
}
f()
x
A5
B10
C20
DError
Attempts:
2 left
💡 Hint
The <<- operator modifies the variable in the nearest parent environment where it exists.
🔧 Debug
advanced
3:00remaining
Why does this closure not remember the updated value?
Consider this code:
make_funcs <- function() {
  funcs <- list()
  for (i in 1:3) {
    funcs[[i]] <- function() i
  }
  funcs
}
fs <- make_funcs()
fs[[1]]()
fs[[2]]()
fs[[3]]()

What is the output of the three calls to fs[[1]](), fs[[2]](), and fs[[3]]()?
R Programming
make_funcs <- function() {
  funcs <- list()
  for (i in 1:3) {
    funcs[[i]] <- function() i
  }
  funcs
}
fs <- make_funcs()
fs[[1]]()
fs[[2]]()
fs[[3]]()
A
[1] 1
[1] 2
[1] 3
B
[1] 3
[1] 3
[1] 3
C
[1] 1
[1] 1
[1] 1
DError in function calls
Attempts:
2 left
💡 Hint
Think about when the variable i is looked up by the functions.
📝 Syntax
advanced
2:00remaining
Identify the error in this closure code
What error does this code produce?
make_adder <- function(x) {
  function(y) {
    x + y
  }
}
add5 <- make_adder(5)
add5("3")
R Programming
make_adder <- function(x) {
  function(y) {
    x + y
  }
}
add5 <- make_adder(5)
add5("3")
AError: non-numeric argument to binary operator
BError: object 'y' not found
CNo error, returns 8
DError: unexpected string constant
Attempts:
2 left
💡 Hint
Check the types of the arguments used in the addition.
🚀 Application
expert
3:00remaining
How many unique environments are created?
Consider this code:
make_funcs <- function() {
  funcs <- list()
  for (i in 1:3) {
    funcs[[i]] <- local({
      x <- i
      function() x
    })
  }
  funcs
}
fs <- make_funcs()
length(unique(sapply(fs, environment)))

What is the output of the last line?
R Programming
make_funcs <- function() {
  funcs <- list()
  for (i in 1:3) {
    funcs[[i]] <- local({
      x <- i
      function() x
    })
  }
  funcs
}
fs <- make_funcs()
length(unique(sapply(fs, environment)))
A3
B1
C0
DError
Attempts:
2 left
💡 Hint
Each call to local creates a new environment for the function.

Practice

(1/5)
1. What is an environment in R programming?
easy
A. A type of loop for repeating code
B. A place where variables and their values are stored
C. A function that takes another function as input
D. A package that extends R's capabilities

Solution

  1. Step 1: Understand the definition of environment

    In R, an environment is a collection where variables and their values are stored together.
  2. Step 2: Differentiate from other options

    Options B, C, and D describe loops, higher-order functions, and packages, which are not environments.
  3. Final Answer:

    A place where variables and their values are stored -> Option B
  4. Quick Check:

    Environment = variable storage [OK]
Hint: Remember: environment stores variables like a box [OK]
Common Mistakes:
  • Confusing environment with a function
  • Thinking environment is a loop
  • Mixing environment with packages
2. Which of the following is the correct way to create a closure in R?
easy
A. f <- function(x) { function() x + 1 }
B. f <- function(x) { x + 1 }
C. f <- function(x) { x <- x + 1 }
D. f <- function(x) { print(x) }

Solution

  1. Step 1: Identify closure structure

    A closure is a function that returns another function which remembers variables from its environment.
  2. Step 2: Check each option

    f <- function(x) { function() x + 1 } returns a function that uses 'x' from the outer function, creating a closure. Others do not return a function.
  3. Final Answer:

    f <- function(x) { function() x + 1 } -> Option A
  4. Quick Check:

    Closure returns function using outer variable [OK]
Hint: Closure = function returning function using outer variables [OK]
Common Mistakes:
  • Not returning a function inside another function
  • Modifying variable without returning a function
  • Confusing print with returning a function
3. What will be the output of the following R code?
make_counter <- function() {
  count <- 0
  function() {
    count <<- count + 1
    count
  }
}
counter <- make_counter()
counter()
counter()
medium
A. Error due to undefined variable
B. [1] 0 followed by [1] 1
C. [1] 1 followed by [1] 1
D. [1] 1 followed by [1] 2

Solution

  1. Step 1: Understand the closure and <<- operator

    The inner function modifies 'count' in the parent environment using <<- and increments it by 1 each call.
  2. Step 2: Trace the calls to counter()

    First call returns 1 (0+1), second call returns 2 (1+1).
  3. Final Answer:

    [1] 1 followed by [1] 2 -> Option D
  4. Quick Check:

    Closure increments count with <<- [OK]
Hint: <<- changes outer variable, so count increases each call [OK]
Common Mistakes:
  • Thinking count resets each call
  • Confusing <- with <<- operator
  • Expecting error due to variable scope
4. Identify the error in this R code that tries to create a closure:
make_adder <- function(x) {
  function(y) {
    x + y
  }
}
add5 <- make_adder(5)
add5(3)
rm(x)
medium
A. The function make_adder is missing a return statement
B. Removing 'x' breaks the closure, causing an error on add5(3)
C. No error; code runs fine
D. The inner function should use <<- to modify x

Solution

  1. Step 1: Understand closure variable dependency

    The inner function depends on 'x' stored in its own dedicated environment created by make_adder.
  2. Step 2: Effect of removing 'x'

    rm(x) removes 'x' from the global environment if it exists, but the closure's environment retains its own 'x' = 5, so add5(3) works fine.
  3. Final Answer:

    No error; code runs fine -> Option C
  4. Quick Check:

    Closure environments are independent of global [OK]
Hint: rm(x) doesn't affect closure's private x [OK]
Common Mistakes:
  • Thinking functions need explicit return
  • Believing <<- is needed to read outer variables
  • Mistakenly thinking rm(x) removes closure's x
5. You want to create a function in R that remembers a secret number and returns a function to check guesses. Which approach correctly uses closures to keep the secret safe?
hard
A. secret_keeper <- function(secret) { function(guess) { guess == secret } }
B. secret_keeper <- function(secret) { secret <- NULL; function(guess) { guess == secret } }
C. secret_keeper <- function(secret) { function(guess) { secret <- guess; TRUE } }
D. secret_keeper <- function(secret) { function(guess) { print(secret); guess } }

Solution

  1. Step 1: Identify closure usage to keep secret

    secret_keeper <- function(secret) { function(guess) { guess == secret } } returns a function that compares guess to secret stored in the closure environment, keeping secret safe.
  2. Step 2: Analyze other options for flaws

    secret_keeper <- function(secret) { secret <- NULL; function(guess) { guess == secret } } sets secret to NULL, losing the secret. secret_keeper <- function(secret) { function(guess) { secret <- guess; TRUE } } changes secret to guess, breaking secrecy. secret_keeper <- function(secret) { function(guess) { print(secret); guess } } prints secret, exposing it.
  3. Final Answer:

    secret_keeper <- function(secret) { function(guess) { guess == secret } } -> Option A
  4. Quick Check:

    Closure keeps secret hidden and accessible only inside [OK]
Hint: Closure hides secret; don't overwrite or expose it [OK]
Common Mistakes:
  • Overwriting secret variable inside closure
  • Exposing secret with print statements
  • Setting secret to NULL before use
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard