Reputation: 29537
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?
Upvotes: 30
Views: 4281
Reputation: 4049
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/
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)
Upvotes: 14
Reputation: 14845
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!
Upvotes: 9