[squeak-dev] Re: BlockClosure vs BlockContext

Julian Fitzell jfitzell at gmail.com
Wed Aug 4 19:09:03 UTC 2010


(sorry, reposting as I didn't reply to all and missed some lists)

On Wed, Aug 4, 2010 at 5:44 PM, John Chludzinski
<john.chludzinski at gmail.com> wrote:
> So what are the semantics to BlockClosure's?  When are the values of temps
> bound to the block?

The *values* aren't "bound". Closures "close over" the dynamic scope
at the point they are defined. This means that the variable references
in the closure refer to whatever variable bindings had those names at
the time the closure was created.

The point of #fixTemps was never to change this behaviour but rather
to make sure that variables defined *local to the closure* (such as
the parameter "a" in the examples below) behaved like unique variables
rather than being shared by all blocks in the same method.

i.e. In a closure image:

blocks := #(1 2 3) collect: [ :a | [ a ] ].
blocks collect: [ :ea | ea value ] "--> #(1 2 3)"

Note that the :a is akin to a method parameter. Every time you call a
method, a new binding is created with that name and assigned the value
passed in. Multiple invocations of the method are not using the same
variable (otherwise recursion wouldn't work). Closures should behave
the same way.

In a non-closure image, however:

blocks := #(1 2 3) collect: [ :a | [ a ] ].
blocks collect: [ :ea | ea value ] "--> #(3 3 3)"

or even more perversely:

blocks := #(1 2 3) collect: [ :a | [ a ] ].
[ :a | ] value: 4.
blocks collect: [ :ea | ea value ] "--> #(4 4 4)"

but with fixTemps it behaves as in the closure image:

blocks := #(1 2 3) collect: [ :a | [ a ]  fixTemps ].
blocks collect: [ :ea | ea value ] "--> #(1 2 3)"


Note that even in a closure image, you *can* change the value of a
block-local variable after the fact (I've added a local variable
because you aren't allowed to change the value of "a", since it's a
parameter):

getters := OrderedCollection new.
setters := OrderedCollection new.
#(1 2 3) do: [ :a |
       |local|
       local := a.
       getters add: [ local ].
       setters add: [ :val | local := val ] ].
getters collect: [ :ea | ea value ]. "--> #(1 2 3)"
setters do: [ :ea | ea value: 9 ].
getters collect: [ :ea | ea value ]. "--> #(9 9 9)"

Hope that helps some (and provides food for thought :) )?



More information about the Squeak-dev mailing list