Style question on recursive generators
Steve Holden
steve at holdenweb.com
Mon Oct 18 11:16:21 EDT 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