Michael Bevilacqua-Linn on 15 Mar 2010 14:36:54 -0700 |
While HOP probably does a better job of explaining closures than I do... When someone says that a language 'has closures', what they generally seem to mean is that the language has first-class functions (usually, more accurately, procedures since most practical languages allow side effects, but that distinction doesn't seem to be made much) that 'close over' their surrounding scope. A first-class function (or procedure) means that there's a facility in the language that allows you to create procedures at execution time, store a reference to them in a variable, basically treat them as you would any other piece of data that your program is working with. Like I mentioned above, the 'closure' refers to the procedure 'closing over'* the scope that it was created in, which just means that the free variables in the procedure are bound in the environment that existed when the closure was created. This sounds impressive and hard to grok, but it's actually pretty clear with an example, so let's see if I can fit one in here. Let's say we have the following psuedocode, in a language that allows nested procedure definitions. defproc outerProcedure(){ def x = 1 def y = 1 print "In outerProcedure" print x print y defproc innerProcedure(){ def y = 2 print "In innerProcedure" print x print y } } An easy way to visual the lexical scope as this program executes is as a linked list of symbol tables. When x and y are defined in outerProcedure, they're placed into a symbol table along with their values. When innerProcedure executes, a new symbol table is created and y is placed in that symbol table (along with its new value). This second table also contains a link back to the table for outerProcedure. To look up the value that a variable is bound to at any given point in the program, start at the bottom-most symbol table and see if there's a binding for the variable, and then work your way up the chain. So in this case, in innerProcedure, we'd get a value of 2 for y and 1 for x, just like we'd expect. So a closure is a structure that contains not only the procedure that you've created, but a way to get at the scope it was defined in. I tend to think of it as having not only the chunk of code, but a linked list of symbol tables like I described above (though I can't imagine that's how it's implemented anywhere outside of CS class...) You can then pass this structure around, add new layers of scope to it, etc. So while C function pointers and closures may serve the same purpose some of the time (you could probably use either to, say, pass a sorting algorithm into a procedure), closures are a lot more powerful, and can help lead to better factored code. Since they carry their scope with them, you can be a lot more sure that some piece of code a hundred thousand lines away hasn't reached in and mucked with some of your state. Also, HOP is worth a browse even for non perl people (like myself). Thanks, MBL * I've never been able to figure out what, if any, this has to do with mathematical closures. I think the term might just be overloaded? On Mon, Mar 15, 2010 at 4:35 PM, <mjd-phillylambda@plover.com> wrote:
|
|