[Pharo-project] Block semantics ....

Eliot Miranda eliot.miranda at gmail.com
Mon Nov 29 23:26:00 CET 2010


On Mon, Nov 29, 2010 at 12:43 PM, James Ladd <james_ladd at hotmail.com> wrote:

>  Hi Eliot,
>
> I was suspecting you might respond, you really know your stuff.
>
> I think I'm more confused now that before but in a good way.
> I have more information thank to you.
>
> My need to fully understand blocks is to implement them in Redline.
>
> Maybe it will be sufficient to 'limit' the use of a block with a
> return to the method in which is was defined?
> ie: Method A can define the block and send it as an argument, but once
> method A has been exited, the block is no longer valid, at least not
> the return part.
>
>
Right.  That's what one gets with nested functions in Pascal.  One cannot
return a nested function in Pascal because a nested function's lexical
bindings are only valid within the enclosing activation.  This allows the
implementation to refer to its lexical bindings by reference, either with a
"static chain" or a "display".  The static chain is the common
implementation technique now.  The head of the static chain is a copy of the
frame pointer of the next lexically-enclosing function, stored in the nested
function and its activation.  Any lexical binding can be reached by
following the static chain.  An alternative technique is a "display", which
is essentially an array of frame pointers, one for each level of nesting,
allowing implementing lexical binding access by a double indirection.

But these are only "downward funargs" because they can only be passed down
the stack.  Smalltalk (and many other languages) provides "full upward
funargs" becaue they can outlive their enclosing activation and be returned.

>
> Does this appear most 'like' how blocks are handled in Pharo?
>
>
Sort of.  The main difference is that in Smalltalks derived from
Smalltalk-80 activation records are first-class objects and so can outlive
their invocation.  i.e. a Smalltalk activation is an object, /not/ space on
a stack.  Under the covers the VM /may/ choose to implement activations in a
stack-like manner, lazily creating objects only when needed (which is what
Cog and VisualWorks do), but that's a hidden optimization and conceptually
creating an activation creates an object.  So there is no conceptual problem
having a block refer to its enclosing activation after that activation has
returned, but obviously the attempt to return a second time must fail
because the place to return to is already in use, or has already been
returned from.

However, apart from return, there is no need to refer to the outer
activation to access lexical bindings.  The scheme is to copy the values of
lexical bindings that can't change while executing a block that refers to
them (e.g. arguments and temps assigned to before a block is created but not
afterwards), and move the lexical bindings that can change off teh stack
into a heap-allocated Array.  You can read about this in excruciating detail
on my blog in
http://www.mirandabanda.org/cogblog/2008/06/07/closures-part-i/,
http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/and
http://www.mirandabanda.org/cogblog/2008/07/24/closures-part-iii-the-compiler/
.


BTW, the Wikipedia page on the Funarg
problem<http://en.wikipedia.org/wiki/Funarg_problem>is a good starting
point for a general discussion of closures in programming
languages.

HTH
Eliot

>
> Rgs, James.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gforge.inria.fr/pipermail/pharo-project/attachments/20101129/d1db007e/attachment.htm>


More information about the Pharo-project mailing list