What does it mean to "close over" something?

4k views Asked by At

I'm trying to understand closures, but literally every definition of a closure that I can find uses the same cryptic and vague phrase: "closes over".

What's a closure? "Oh, it's a function that closes over another function."

But nowhere can I find a definition of what "closes over" means. Can someone explain what it means for Thing A to "close over" Thing B?

2

There are 2 answers

6
Matt On BEST ANSWER

A closure is a pair consisting of a code pointer and an environment pointer. The environment pointer contains all of the free variables of a given function. For example:

fun f(a, b) = 
  let fun g(c, d) = a + b + c + d
  in g end

val g = f(1, 2)
val result = g(3, 4)  (*should be 10*)

The function g contains two free variables: a and b. If you are not familiar with the term free variable, it is a variable that is not defined within the scope of a function. In this context, to close over something, means to remove any occurrences of a free variable from a function. The above example provides good motivation for closures. When the function f returns, we need to be able to remember what the values of a and b are for later. The way this is compiled, is to treat function g as a code pointer and a record containing all the free variables, such as:

 fun g(c, d, env) = env.a + env.b + c + d
 fun f(a, b, env) = (g, {a = a, b = b})
 val (g, gEnv) = f(1, 2)
 val result = g(3, 4, gEnv)

When we apply the function g, we supply the environment that was returned when calling function f. Note that now function g no longer has any occurrences of a variable that is not defined in its scope. We typically call a term that doesn't have any free variables as closed. If you are still unclear, Matt Might has an excellent in depth explanation of closure conversion at http://matt.might.net/articles/closure-conversion/

Same example in Javascript

Before closure conversion

function f(a, b){
    function g(c, d) {
        return a + b + c + d
    }
    return g
}

var g = f(1, 2)
var result = g(3, 4)

After closure conversion:

function g(c, d, env) {
    return env.a + env.b + c + d
}

function f(a, b, env) {
    return [g, {"a": a, "b": b}]
}

var [g, gEnv] = f(1, 2)
var result = g(3, 4, gEnv)
3
Icaro On

From apple documentation

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.

But what that means?

It means that a closure captures the variables and constants of the context in which it is defined, referred to as closing over those variables and constants.

I hope that helps!