[net.lang.st80] The wonderfulness of block arguments

obrien@randvax.UUCP (Michael O'Brien) (08/30/86)

I've been noodling around the hierarchy for some time now, and have come
across one really peculiar construction that doesn't seem to be mentioned
anywhere, but which seems to work reliably.  It seems to be a sneaky way
to pass a pointer to a temporary variable (at least) as well as several
other things.

If a block argument has the same name as a temporary variable, they seem
to be the same thing:

| foo |
foo _ 1.
[:foo] value: 3.
foo _ foo + 1

This evaluates to 4, not 2.  In particular, if the block [:foo] is handed off
as the argument to a message selector, that other method can change the value
of "foo" seen on return in the local method.  This is used in the file system
code, at least.

Also, block arguments which are uniquely named are still available after the
block returns (but not before!).  Hence,

[:fum] value:3.
fum _ fum + 1

is legal and returns 4.  However,

fum _ fum + 1.
[:fum] value:3

won't compile.

It is entirely possible that there is some punning going on, and that if the
block is not evaluated, the block argument will refer to some other variable
or to random storage.  I don't know enough about the compiler to say.  Still,
it seems mightily peculiar, if sometimes useful.

Comments?
-- 
Mike O'Brien
The Rand Corporation

{sdcrdcf,decvax}!randvax!obrien
obrien@rand-unix.arpa

allenw@tekchips.UUCP (Brock) (09/02/86)

> I've been noodling around the hierarchy for some time now, and have come
> across one really peculiar construction that doesn't seem to be mentioned
> anywhere, but which seems to work reliably.  It seems to be a sneaky way
> to pass a pointer to a temporary variable (at least) as well as several
> other things.
> 
> If a block argument has the same name as a temporary variable, they seem
> to be the same thing:
> 
> | foo |
> foo _ 1.
> [:foo] value: 3.
> foo _ foo + 1
> 
> This evaluates to 4, not 2.  In particular, if the block [:foo] is handed off
> as the argument to a message selector, that other method can change the value
> of "foo" seen on return in the local method.  This is used in the file system
> code, at least.
> 
> Also, block arguments which are uniquely named are still available after the
> block returns (but not before!).  Hence,
> 
> [:fum] value:3.
> fum _ fum + 1
> 
> is legal and returns 4.  However,
> 
> fum _ fum + 1.
> [:fum] value:3
> 
> won't compile.
> 

Block arguments are ALWAYS represented as method temporaries of the block's
home context.  The use of a symbol as a block argument implicitly declares
it to be a method temporary.  Following such an implicit declaration
the variable may be used as if it had been explicitly declared.  All occurences
of a variable name within a method (and any contained blocks) refer to the
same storage location.

> It is entirely possible that there is some punning going on, and that if the
> block is not evaluated, the block argument will refer to some other variable
> or to random storage.  I don't know enough about the compiler to say.  Still,
> it seems mightily peculiar, if sometimes useful.
> 
> Comments?
> -- 
> Mike O'Brien
> The Rand Corporation
> 
> {sdcrdcf,decvax}!randvax!obrien
> obrien@rand-unix.arpa

The standard compiler and virtual machine always allocates space for block arguments
in the temporary frame of the enclosing method context.  Evaluation of a block
will not effect the existance of the storage for its arguments, only what values they
contain. (All variables are initialized to nil)

In general the semantics of block arguments are poorly defined by the Smalltalk language
"definition" and the semantics which are implicitly defined by the standard implementations
have a number of ugly implications (for example, blocks are not reentrant and hence not
recursively callable).  This is an area where Smalltalk-80 could use some major design
cleanup.

				Allen Wirfs-Brock
				Tektronix, Inc.

jans@tekecs.UUCP (Jan Steinman) (09/02/86)

In article <492@randvax.UUCP> obrien@randvax.UUCP (Michael O'Brien) writes:
>If a block argument has the same name as a temporary variable, they seem
>to be the same thing...
>
>It is entirely possible that there is some punning going on, and that if the
>block is not evaluated, the block argument will refer to some other variable
>or to random storage.

Block arguments ARE temporary variables, at least from the Virtual
Machine's point of view.  (The Blue Book has a good discussion of this on
pages 559-560.)  The behavior cited is due to the scoping rules of the
Smalltalk compiler -- temporaries cannot be used before they are declared.
If the "[:blockArgumentName|" construct is thought of as an out-of-place
temporary declaration, the described behavior makes sense.

Block arguments are initialized to "nil", as are all temporary variables.

-- 
:::::: Artificial   Intelligence   Machines   ---   Smalltalk   Project ::::::
:::::: Jan Steinman		Box 1000, MS 60-405	(w)503/685-2956 ::::::
:::::: tektronix!tekecs!jans	Wilsonville, OR 97070	(h)503/657-7703 ::::::