Style question on recursive generators

Steve Holden steve at holdenweb.com
Mon Oct 18 17:16:21 CEST 2004


Carlos Ribeiro wrote:
> On Mon, 18 Oct 2004 16:27:43 +0200, Alex Martelli <aleaxit at yahoo.com> wrote:
> 
>>Carlos Ribeiro <carribeiro at gmail.com> wrote:
>>   ...
>>
>>>Yes, that's a good point, and it's one of the reasons I tend to prefer
>>>the generator now. But anyway, it's just me, or does the 'chained
>>>yield' look ugly to someone else? It may be just a question of getting
>>>used to it, but nevertheless it's bugging me...
>>
>>I'm not sure why it should look ugly to you.  What alternatives would
>>you consider non-ugly for the common (in any generator) idiom:
>>    for x in y: yield x
>>?
>>
>>Perhaps some syntax hack such as a new statement keyword 'yieldall'
>>where the above idiom could be expressed as
>>    yieldall y
>>?  Or some other syntax hack such as 'yield<<y', or 'yield from y',
>>ditto?  Personally, it would seem to me that such special syntax would
>>be just one more bit of Python to learn, without substantial benefits,
>>but that's because I see nothing ugly in today's idiom -- it does just
>>what it says, plainly and unpretentiously...
> 
> 
> Generally speaking, new keywords hardly solve any problem; in fact,
> they create new problems of their own :-) In this case, my main gripe
> is that the code doesn't read as naturally as the simple recursive
> version, because of the double for loop. Its also strange because I
> often have to stop and think, "what am I yielding now". For deeply
> nested recursive cases there is also the feeling that the yield chain
> may prove to be a performance dog, but that's should not be the main
> point here anyway.
> 
> I have a strange idea in the back of my mind that tells me that a
> possible solution would be to have any of the nested yields to
> immediately return the result to the original caller. In this case, I
> would write my code this way:
> 
> def walk(self):
>    """generator-based recursive tree traversal"""
>    yield child
>    for child in childs:
>         transfer child.walk()
> 
> It's quite weird -- a generator plus a direct flow-of-execution
> transfer. It's not a goto, its not a co-routine... It requires a new
> keyword ('transfer', in this case), which _is_ a real problem --
> something like this can't be lightly proposed. In this case, it's just
> a thought experiment, at this point; nothing serious, and far from a
> proposal.
> 
I can see why this might seem attractive, but in point of fact it would 
do little more than the elimination of tail recursion, and would have 
similar disadvantages - it wouldn't be possible to get useful tracebacks 
in the event that problems occurred.

If a data structure is recursive then a recursive generator or a 
recursive function is often the bext way to handle it, and yielding a 
result to another yield statement (at however many levels) surely isn't 
problematical enough to remove a desirable regularity from the language 
and its implementations.

regards
  Steve
-- 
http://www.holdenweb.com
http://pydish.holdenweb.com
Holden Web LLC +1 800 494 3119




More information about the Python-list mailing list