[Python-ideas] A Continuations Compromise in Python

Arnaud Delobelle arnodel at googlemail.com
Sun May 3 09:10:26 CEST 2009


On 3 May 2009, at 07:44, Carl Johnson wrote:

> I have a question about the implementation of "yield from." I recall
> hearing some talk about optimizing the stack in "yield from," but I
> didn't catch all of the details. I take it that there will be some
> steps taken to ensure that yield from's yield from their inner most
> yielder without having to touch base at all the objects in between
> whoever is asking for the value and whoever is giving it. That being
> the case, will this example implementation of a linked list still blow
> the stack for lists bigger than 1,000 items or not?
>

I haven't kept up with recent threads about yield-from but in its  
early stages at least the patch did still 'touch base' all objects in  
between, but at C-speed rather than at Python-speed.  However I'm  
pretty sure it would be possible to short-ciruit this, but a trace of  
the stack of call still needs to be kept if the yield-from is followed  
by more processing in the generator function (IOW, if it's not a tail  
yield-from).

> class LinkedList:
>    def __iter__(self):
>        yield self.value
>        if self.link: yield from self.link
>
> If it does still blow up the stack, then it's no big deal, but if this
> won't blow the stack up anymore, then it seems like there's very
> little difference between the kind of recursive programming invited by
> "yield from" and the kind of recursive programming invited by
> "continue object". If you hate reading TCO code (and I take this to be
> the #1 objection to adding TCO to Python, though there are also more
> technical reasons), you're still going to get it, only using "yield
> from" instead of "continue". So in that case, "continue" and "yield
> from" should be thought of as a pair of stack optimizers, one for
> functions and one for generators.

So 'continue f(x)' could be spelt 'return from f(x)'?

But it's not the same anyway, because yield-from can be a tail-call or  
not, so the parallel would be more something like this:

functions:
     return f(x)   # normal call
     continue f(x) # optimized tail call

generators:
     yield from gen    # normal yield-from
     continue from gen # optimized tail yield-from

In fact, 'continue from gen' would make sense even if it is not a tail  
yield-from.  It would yield control to gen and never come back.  OK I  
have to stop writing whatever comes to my mind now :)

-- 
Arnaud




-- 
Arnaud




More information about the Python-ideas mailing list