12.3.6 Closures
This section describes closures — an advanced concept. If you do not understand or wish to study this section, you can safely skip it.
Consider the following example:
define method call-and-show (function :: <function>, #rest arguments)
format-out("The result is %=.\n", apply(function, arguments));
end method call-and-show;
define method show-next (x :: <integer>)
call-and-show(method () x + 1 end method);
end method show-next;
When we execute this code, we get the expected result:
? show-next(41); The result is 42.
But why did we get that result? We created an anonymous method in show-next, and passed that anonymous method into a completely separate method (call-and-show), where x is not bound to anything. And yet, when the call-and-show method executed the anonymous method that we made, somehow the anonymous method could still access the x binding. We got this reasonable result because the method statement can create a special kind of method called a closure.
Recall that Dylan has two kinds of variable: module variables and local variables. A local variable is defined explicitly by a let or local declaration, and implicitly by a function call, when a method's parameters are initialized to that method's arguments. Local variables are defined within a limited lexical scope — that is, they bind a name to a value only within a particular textual portion of the program. This portion of the program is that part of the innermost body that follows the definition of the local variable.
A method statement or a local declaration can define a method in a portion of a program where local variables are in effect. In the preceding example, we use a method statement to define a method inside the body of the show-next method, where the local variable x (the parameter for the show-next method) is bound to the argument to show-next. The method that we define inside show-next refers to that local variable x.
In general, when a program exits a body, the local variables defined inside that body cease to be defined, and it is an error for the program to refer to those variables. But there is an exception. If we use method or local to define a method, and if we then execute that method outside the body in which we define it, the method can still refer to the local variables that were in effect when the method was defined. Such a method is called a closure.
A closure is a method that closes over or captures local variables that are in effect when the method is defined and that are referred to in the body of the method. The closure created by the method statement in our example captures the local variable x. So, even though the local variable x is not defined in the lexical scope of the call-and-show method, the closure called by call-and-show can access the captured binding of x.
For examples of closures as iteration or mapping functions for collections, see Section 11.3.5, page 146, and Section 11.3.7, page 147.




