Adding loop primitives/optimizations (was Making Set/Dictionaryetc. loops more robust)

Joshua Scholar jscholar at access4less.net
Thu Dec 2 05:08:01 UTC 2004


I should have included a link in my answer to Richard O'Keefe.

Here is the Squeak Swiki Page I was talking about:
http://minnow.cc.gatech.edu/squeak/331
It's called "Are Squeak blocks like Scheme blocks"

...

"'do' is also defined in terms of rewriting to a recursive 'lambda'."

Anyway I don't really understand how recursive lambdas can give you
iteration while reusing the same environment - recursion creates a new
environment with each call.  Yes I know about tail recursion - but if you
were to capture a variable in a Scheme recursive loop (that is store a
closure accessing that variable), as the Swiki example does with a Smalltalk
iteration loop, then each iteration WOULD have to be a separate variable.  I
think that if a variable is captured then the tail recursion optimization
must be disallowed.

Think about what recursion looks like in C.
void RecureLoop(int i)
{
    if (i<10)  RecureLoop(i+1);
    ...

If you call  RecureLoop(1), then when i=10 that means there is another
instance of i on the stack that holds a 9, another above that with an 8
another above that with a 7...  You can see that capturing a variable in a
recursive lambda iteration means that each captured variable is unique.

Thus "Scheme _does_ create a new environment (in principle) for each loop
_entry_ but not for each loop _iteration_." is only true when the tail
recursion optimization succeeds and that can only happen if the environment
isn't captured.

Anyway, in Smalltalk iteration is primary, not recursion.  Is there a
tail-recusion optimization?

But now that I think about it, the only loops that are primitive right now
are while and number to: loops... Won't blocks have to create a new
environment on each invocation?  And primitive looping blocks are the only
blocks that will know the difference between running the first first time
and running again, so therefor any block sent to collect: will be nested
inside of a primitive iterator, but being nested in the iteration block not
being the iteration block the they won't know the difference between a first
invocation and a second one and so they'll have to create a new environment
each time.

Am I missing something?

Joshua Scholar




More information about the Squeak-dev mailing list