Concepts of Programming Languages

(Sean Pound) #1
9.12 Closures 431

When subprograms can be nested, in addition to locals and globals, the
referencing environment of a subprogram can include variables defined in all
enclosing subprograms. However, this is not an issue if the subprogram can be
called only in places where all of the enclosing scopes are active and visible. It
becomes an issue if a subprogram can be called elsewhere. This can happen if
the subprogram can be passed as a parameter or assigned to a variable, thereby
allowing it to be called from virtually anywhere in the program. There is an
associated problem: The subprogram could be called after one or more of its
nesting subprograms has terminated, which normally means that the variables
defined in such nesting subprograms have been deallocated—they no longer
exist. For the subprogram to be callable from anywhere in the program, its
referencing environment must be available wherever it might be called. There-
fore, the variables defined in nesting subprograms may need lifetimes that are
of the entire program, rather than just the time during which the subprogram
in which they were defined is active. A variable whose lifetime is that of the
whole program is said to have unlimited extent. This usually means they must
be heap-dynamic, rather than stack-dynamic.
Nearly all functional programming languages, most scripting languages,
and at least one primarily imperative language, C#, support closures. These
languages are static-scoped, allow nested subprograms,^12 and allow subpro-
grams to be passed as parameters. Following is an example of a closure written
in JavaScript:

function makeAdder(x) {
return function(y) {return x + y;}
}

...
var add10 = makeAdder(10);
var add5 = makeAdder(5);
document.write("Add 10 to 20: " + add10(20) +
"
");
document.write("Add 5 to 20: " + add5(20) +
"
");


The output of this code, assuming it was embedded in an HTML document
and displayed with a browser, is as follows:

Add 10 to 20: 30
Add 5 to 20: 25

In this example, the closure is the anonymous function defined inside the
makeAdder function, which makeAdder returns. The variable x referenced
in the closure function is bound to the parameter that was sent to makeAdder.


  1. In C#, the only methods that can be nested are anonymous delegates and lambda
    expressions.

Free download pdf