Iterators? (Was: Squeak practical use? ...)

Scott A Crosby crosby at qwes.math.cmu.edu
Thu Jan 31 04:04:31 UTC 2002


On Wed, 30 Jan 2002, Andrew C. Greenberg wrote:

> This effect can be trivially accomplished by other means:
>
> method: aParm
>
> 	self doSomeCode. . .
> 	^self method: anExpression
>
> -- coded as --
>
> method: aParm
> 	| value |
> 	value := aParm.
> 	[self doSomeCode. . .
> 	 value := anExpression]
> 		repeat
>

Simple tail recursion can look this way, but more complicated tail
recursion doesn't map as pleasantly:

foo: x ifSucces: succBlock ifFail: failBlock
   blah1 ifTrue: [ ^succBlock value ]
   blah2 ifTrue: [ ^failBlock value ]
   succBlock := [ blah . [^sucBlock value]]

Which is code done in the explicit continuation style. This is especially
good for, for example, parsers.

Also, you can suspend and restart these continuations at any time easily.
Without tail recursion, this isn't possible.


> The general translation, of course, always looks more gross than a more
> ordinarily coded iteration.  Appears to do what you want.  (I don't
> recall whether repeat is inlined.  If not, add ". true" to the block and
> replace repeat with "whileTrue").  The bottom line is that tail
> recursion is semantically indistinguishable from a corresponding and
> straightforward iteration.

In the case of mutual tail recursion, not unless your language has
'goto'.. You'd need something like:

[
  state == #foo ifTrue: [ .... state _ #baz ]
  state == #bar ifTrue: [ .... state _ #foo ]
  true] whileTrue.

Which is especially nasty if the different clauses should be different
methods, or even in different classes.


> This reduces the problem to the question whether the proposed
> semantic/syntactic sugar outweighs the costs of introducing the
> unfortunate notion of "pragma" to Smalltalk, or whether the cost of
> automatic optimization would outweigh the benefit of losing the current,
> presently expected, debugger behavior.

Automatic tail-call optimization. If you activate tail-call for a class,
all methods in that class automatically do all applicable methods through
a tailcall. Or, make it system-wide, and recompile code.

Tailcall's are importantant from a theoretical perspective. Once you have
them and closures, you can implement the real elegant and useful
algorithms. You also have the option of using new styles of coding,
especially proof strategies and parsing strategies.


Scott





More information about the Squeak-dev mailing list