on 1/2/01 8:49 AM, Bob Arning at arning@charm.net wrote: ...
This has led me to wonder whether it would be better if Smalltalk had (horror of horrors) a GOTO. Since the implementation of this method depends on the fact that the optimized bytecodes emit GOTO, perhaps it would be clearer (and more robust, should someone decide to remove the compiler optimization) if it were actually written that way.
A "structured" Goto is exactly how I implemented iteration, exceptions, and backtracking in Avail:
http://www.ericsworld.com/Mark/HTML/Avail.html
The process model is a little strange. Basically, most of the objects in Avail are immutable, so each nybblecode is defined in terms of taking an immutable chain of immutable contexts and producing another immutable chain of immutable contexts. A process contains a mutable variable that holds this immutable chain of contexts. Executing a process is defined as executing nybblecodes until the process stops, feeding the context chain resulting from a nybblecode into the next one. Lots of VM optimizations make normal usage of iteration as "intrinsically efficient" as Smalltalk.
The syntax is fairly plain:
[ $someLabel; Print "hello"; Restart someLabel; ]();
Alternatively, you can escape from nested blocks with the same kind of mechanism:
[ $someLabel; if 2+2=5 then [Exit someLabel;]; Print "2+2=4"; ]();
Just to clear things up, the "$_" notation declares a label, and is always at the start of the block being labeled. The label is just a declaration and initialization of a local variable (but not assignable, similar to arguments in most Smalltalks). In the expression "Exit someLabel", we are simply invoking the "Exit_" (multi)method with the immutable context found in the variable "someLabel".
Trick: If you're tired of relying on Compiler tricks in Smalltalk to implement space-efficient iteration, just do this:
... here := thisContext pc. ... thisContext pc: here. ...
It probably won't work, but it's more accurate pseudocode than the recursive version in whileTrue:.