Newsgroups: comp.lang.smalltalk
Path: cantaloupe.srv.cs.cmu.edu!das-news.harvard.edu!news2.near.net!MathWorks.Com!news.duke.edu!convex!cs.utexas.edu!howland.reston.ans.net!EU.net!sun4nl!news.nic.surfnet.nl!utciva.civ.utwente.nl!infnews.cs.utwente.nl!koopmans
From: koopmans@cs.utwente.nl (Piet Koopmans)
Subject: Re: Interesting Block Behavior
Message-ID: <Cwvzn2.7Fv@cs.utwente.nl>
Originator: root@cerberus
Sender: usenet@cs.utwente.nl (News System)
Nntp-Posting-Host: cerberus.cs.utwente.nl
Organization: University of Twente, Dept. of Computer Science
References:  <Pine.A32.3.90.940928100201.28469D-100000@swim5.eng.sematech.org>
Date: Thu, 29 Sep 1994 10:25:49 GMT
Lines: 63


In article <Pine.A32.3.90.940928100201.28469D-100000@swim5.eng.sematech.org>, 
"William D. Gooch" <goochb@swim5.eng.sematech.org> writes:

|> For a good time, file the following class definition into VisualWorks 1.0 
|> (or your favorite Smalltalk) and try it out, viz: BlockTester new runBlock.
|> I'd be interested to hear (1) plausible explanations of why it does what it 
|> does in PPST,

I have tried it using ParcPlace's Objectworks\Smalltalk(R), Release 4.1a, which
is compatible with VisualWorks, as I'm told.

The execution stops with a 'Context cannot return'-exception.

This is perfectly logical, since the execution of a return statement in
Smalltalk (^someObject), even when it is part of a block (like the ^foo), will
cause the METHOD of which it is a part of (initBlock in this case) to return.
The return statement cannot be used to return a value of a block: the value
returned by a block is the value of the last statement executed in the block.

The execution of the initBlock method just initializes the testBlock instance
variable with the block
	[foo := 'hi there'.
	self answerFoo ifTrue: [^foo].
	false]
Then, the initBlock method finishes when it executes the ^self statement. The
^foo statement will not have been executed at this point. This will happen when
the runBlock method requests the value of the testBlock instance variable.
The statements of the block will be executed and eventually the ^foo statement
too. Since the initBlock method already has finished, it cannot do this again
and therefore the 'Context cannot return'-exception will be raised.

As a beside: a Context holds the execution state of a method (a MethodContext)
or a block (a BlockContext). It holds among others a stack, the program counter
and a reference to the executing method.


|> (2) discussion of what it should do,

As stated above, it does exactly what it should do. I can only guess what
YOU WANT that it should do. Probably you want the block to return foo in one
case and false in the other. The value returned by a block is the value of the
last statement executed in the block. So you could write
	[| blockValue |
	foo := 'hi there'.
	self answerFoo
		ifTrue: [blockValue := foo]
		ifFalse: [blockValue := false].
	blockValue].


|> and (3) descriptions of what it does in other dialects.
Sorry, can't help you with that.



Piet

 _____ _____
  | |    |	Piet S. Koopmans		koopmans@cs.utwente.nl
 /  |     -	TRESE Project			+31 53 894191 / +31 53 309808
		Dept. of Computer Science	http://www_trese.cs.utwente.nl/
		University of Twente, Enschede, The Netherlands
