Challenge - 5 Problems
Environment and Closures Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate2: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()Attempts:
2 left
💡 Hint
Think about how the <<- operator changes the variable in the parent environment.
✗ Incorrect
The inner function increments 'count' in the parent environment each time it is called, so the first call returns 1, the second returns 2.
❓ Predict Output
intermediate2: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()
xR Programming
x <- 5 f <- function() { x <- 10 g <- function() { x <<- 20 } g() x } f() x
Attempts:
2 left
💡 Hint
The <<- operator modifies the variable in the nearest parent environment where it exists.
✗ Incorrect
The <<- operator in g() modifies the global x, changing it from 5 to 20. The local x inside f() remains 10, but the global x is 20 after f() runs.
🔧 Debug
advanced3:00remaining
Why does this closure not remember the updated value?
Consider this code:
What is the output of the three calls to
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]]()Attempts:
2 left
💡 Hint
Think about when the variable i is looked up by the functions.
✗ Incorrect
All functions capture the same variable i, which after the loop ends has the value 3. So all functions return 3.
📝 Syntax
advanced2: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")Attempts:
2 left
💡 Hint
Check the types of the arguments used in the addition.
✗ Incorrect
Adding a number and a string causes a type error in R, resulting in 'non-numeric argument to binary operator'.
🚀 Application
expert3:00remaining
How many unique environments are created?
Consider this code:
What is the output of the last line?
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)))Attempts:
2 left
💡 Hint
Each call to local creates a new environment for the function.
✗ Incorrect
Using local inside the loop creates a new environment for each function, so there are 3 unique environments.