Smalltalk Blocks And Closures

A Smalltalk Block is an object. That object is an instance of Block (or a similarly-named class). If the block has no parameters, as in [fred+ethel], it responds to the message #value, and that message answers, in this case, the value of the sum of fred and ethel. Those variables are bound to whatever they were bound to when the block was created.

Suppose a class Lucy, with instance variables fred and ethel. The class includes a method #getBlock:

Lucy>>getBlock ^[fred + ethel]

and creation methods

Lucy class>>fred: fredInteger ethel: ethelInteger ^self new setFred: fredInteger ethel: ethelInteger

Lucy>>setFred: fredInteger ethel: ethelInteger fred := fredInteger. ethel := ethelInteger.

We do the following code:

lucy := Lucy fred: 10 ethel: 15 block := lucy getBlock. val := block value.

val will contain 25. We can hold on to that block as long as we want, send it value whenever we want. The block is bound to the instance variables of the lucy object we created. If we sent lucy messages changing its variables, then the next send of value would get the new answer:

lucy setFred: 1 ethel: 1. newVal := block value.

newVal will be 2.

So, as I understand closures in the Lisp sense, a Smalltalk block is in fact a closure bound to the variables in effect at the time of creation. Holding on to the block can hold on to the object in question. It is generally considered very poor programming style to pass blocks around and hold on to them for extended periods. It's an artifact of the language design that blocks are used for conditionals, but these are generally ephemeral and not held on to for ages. Other Smalltalk wizards: the above is off the cuff. Replace or improve it as you will. -- Ron Jeffries

The phrase "closure" came from the functional programming language community. If you really want to understand closures, read StructureAndInterpretationOfComputerPrograms, one of the great books of computer science.