R Expert · Lesson 1 · On the house

Closures and factories

Factory functions, lexical capture, private env state. Lesson 1 is free — on the house.

Lessons · R Expert · Lesson 1 of 10 · On the house

Closures and factories

Factory functions, lexical capture, private env state.

Illustration for R
Lesson 1 is on the house.

A factory returns a function that closes over bindings from the factory's frame. Those free variables stay live in the returned function's enclosing environment — lexical capture, not a copy of values at call time for mutable cells.

Prefer a private e <- new.env(parent = emptyenv()) (or a list of cells updated via <<- only inside the factory) over top-level <<-. The still uses assign/get on a sealed env so state is private and does not pollute .GlobalEnv.

environment(f) of the returned closure is the factory frame (or the private env you attached). Two factories yield independent counters: each closure owns its own captured cell.

local({ ... }) can also mint a closure with a fresh frame. Expert rule: return functions that close over state; avoid <<- walking into .GlobalEnv for library code.

Misses: assuming each call to the factory shares one global counter, using Python nonlocal keywords, or mutating a captured numeric with n <- n + 1 without <<-/assign (that creates a local n and leaves the outer cell unchanged).

closures-factories

make_counter <- function(start = 0L) {
  e <- new.env(parent = emptyenv())
  assign("n", as.integer(start), envir = e)
  function(step = 1L) {
    assign("n", get("n", envir = e) + as.integer(step), envir = e)
    get("n", envir = e)
  }
}
a <- make_counter(0L)
b <- make_counter(10L)
print(c(a(), a(2L), b(), environment(a) != environment(b)))
Match this when you type.

Quiz

What does a factory return here?

Quiz

Why use new.env(parent = emptyenv()) for the cell?

Quiz

How do a and b stay independent?

Quiz

What goes wrong with n <- n + 1 inside the closure without <<- or assign?

Check

Match the still for: Closures and factories.

Open-book: the answers are on this page. Pass every quiz and check (5) to mark the lesson done. This visit: 0/5.