Full Closures - when do they close?
Robert Withers
withers at vnet.net
Mon Jan 31 16:03:03 UTC 2000
Jesse Welton wrote:
>
> Robert Withers wrote:
> >
> > > Another point. Jesse Welton already pointed out that objects are not copied
> > > by closures. If two closures refer to same object through their variables,
> > > changes made using one closure will be visible through another. it is
> > > important that not only objects are not copied, the bindings are not copied
> > > as well. Two closures created within the same environment see the same
> > > bindings, so changes done to a variable of that environment from one closure
> > > are visible from another. For example:
> > >
> > > | cell |
> > > ^Array
> > > with: [:arg | cell := arg]
> > > with: [cell]
> >
> > -- ??? Really?? This surprises me. I thought that a closure would
> > have it's own binding seperate from any other binding. This is
> > different that two bindings holding the same reference and changing the
> > internal state of that reference. Aren't you saying that two bindings
> > pointing to the same reference and one changes the reference, then the
> > other binding will also have a changed reference?
>
> Yes, this is exactly right. This is necessary to allow (among other
> things) assignments to propagate upwards. Consider:
>
> | sum |
> sum := 0.
> 1 to: self length do: [ :i | sum := sum + self at: i ].
> ^sum
>
> In order from something like this to work, "sum" must name the same
> reference both within and without the block.
ugh! This of course makes sense from a usability standpoint but that
takes me back to:
Method
| answer |
answer := Array new: 5.
1 to: 5 do:
[:i |
answer at: i put: [:arg | arg * i]].
^answer
Since we are 2 levels deep, each time through the loop we have a
different binding for i, so each inner block gets a seperate binding.
If this was:
Method
| answer i |
answer := Array new: 5.
i := 1.
answer at: i put: [:arg | arg * i]].
i := 2.
answer at: i put: [:arg | arg * i]].
i := 3.
answer at: i put: [:arg | arg * i]].
i := 4.
answer at: i put: [:arg | arg * i]].
i := 5.
answer at: i put: [:arg | arg * i]].
^answer
Then all five blocks would have i = 5. Is it so?
-Rob
> -Jesse
--
--------------------------------------------------
Smalltalking by choice. Isn't it nice to have one!
More information about the Squeak-dev
mailing list
|