[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