["BUG"][FIX?]Incorrect Pseudo-Code for #whileTrue:/#whileFalse:?
arning at charm.net
Mon Jan 1 20:25:40 UTC 2001
On Mon, 1 Jan 2001 13:29:44 -0500 "Andrew C. Greenberg" <werdna at mucow.com> wrote:
>It's possible that I'm just not getting it, but it would appear that
>the pseudo-code for #whileTrue; and #whileFalse: is incorrect. Even
>if I were right, it is still the height of pedantry on my part to
>call this a bug, since the code is never executed due to compiler
Actually, it is executed when the receiver is not a literal block. Code such as
| b x |
x _ 0.
b _ [(x _ x + 1) < 10].
b whileTrue: [Transcript show: x printString; cr].
will cause the method in BlockContext to be executed.
>Nevertheless, perhaps it would be more aesthetically
>pleasing to have pseudo-code here that would work if the compiler did
>not inline loops?
With one exception, the current code does work. If you disable inlining of #whileTrue: by changing MessageMode>>transformWhile: to
| x |
x _ 0.
[(x _ x + 1) < 10] whileTrue: [Transcript show: x printString; cr].
will use the code in BlockContext and will run successfully, UNLESS you recompile BlockContext>>whileTrue:, at which point you do encounter the infinite loop.
>The present code in BlockContext is:
>> "Ordinarily compiled in-line, and therefore not overridable.
>> This is in case the message is sent to other than a literal block.
>> Evaluate the argument, aBlock, as long as the value of the
>>receiver is true."
>> ^ [self value] whileTrue: [aBlock value]
>But it would appear to me that this code would infinite loop for so
>long as these valuations do not result in a walkback. In either case
>the behavior appears both undefined and incorrect for most
>BlockContext instances and arguments. Perhaps something like the
>following would yield the desired result?
> ^ self value ifTrue: [aBlock value. self whileTrue: aBlock]
>(and in the case of #whileFalse, use #ifFalse instead).
Umm... this could eat up memory in a hurry. Add this to BlockContext
^ self value ifTrue: [aBlock value. self whileTrueToo: aBlock]
and then evaluate
| x |
x _ 0.
[x = 999 ifTrue: [self halt]. (x _ x + 1) < 1000] whileTrueToo: .
and look at the stack in the debugger. It would seem to me that, absent the optimization of #whileTrue: (at least in #whileTrue: itself), some sort of tail recursion handling would be required and I don't think that would be easy.
More information about the Squeak-dev