Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #93759 > unrolled thread

Re: Possibly Pythonic Tail Call Optimization (TCO/TRE)

Started byChris Angelico <rosuav@gmail.com>
First post2015-07-13 23:56 +1000
Last post2015-07-13 23:56 +1000
Articles 1 — 1 participant

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-13 23:56 +1000

#93759 — Re: Possibly Pythonic Tail Call Optimization (TCO/TRE)

FromChris Angelico <rosuav@gmail.com>
Date2015-07-13 23:56 +1000
SubjectRe: Possibly Pythonic Tail Call Optimization (TCO/TRE)
Message-ID<mailman.467.1436795813.3674.python-list@python.org>
On Mon, Jul 13, 2015 at 11:46 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> On Mon, Jul 13, 2015 at 6:34 AM, Chris Angelico <rosuav@gmail.com> wrote:
>> On Mon, Jul 13, 2015 at 10:00 PM, Antoon Pardon
>> <antoon.pardon@rece.vub.ac.be> wrote:
>>> On 07/13/2015 01:28 PM, Chris Angelico wrote:
>>>> Why is it worth writing your code recursively, only to have it be
>>>> implemented iteratively?
>>>
>>> Because sometimes, it is easier to think about the problem recursively.
>>
>> Can you give me an example that (a) makes a lot more sense recursively
>> than iteratively, and (b) involves just one tail call?
>
> Why does (b) matter? If the function has more than one tail call, it
> doesn't matter which one you hit -- either way it's a tail call and
> the stack frame is no longer needed.

Oops. I meant "involves just one point of recursion". When you
traverse a tree, only one can be a tail call, because after the other,
you still have more processing to do. Most problems that I've found to
work recursively and not iteratively have involved multiple branches -
consider a simplistic solution to the Eight Queens problem that places
a queen, then calls itself to place another queen:

def eightqueens(positions=()):
    for i in range(8):
        if i not in positions:
            # TODO: check for the diagonals
            result = eightqueens(positions + (i,))
            if result: return result
    return None

While it can do the classic "call self, return result", it has to
conditionally _not_ do that and keep on going. While this algorithm
can be implemented iteratively, it's a reasonable show-case for
recursion; but not for tail recursion, because one call to
eightqueens() might result in more than one chained call, so I don't
think there's any way for TCO to kick in here.

What I'm asking for is an example of something that can have the tail
calls optimized away, and yet still looks cleaner - preferably,
*significantly* cleaner - in its recursive form than in its
corresponding iterative form. Considering that an iterative function
can maintain state that isn't in the parameters, I'm dubious that such
a thing exists outside of the deranged minds of functional
programmers. (Very much deranged. If you consider that a recursive
factorial just uses addition and subtraction, while an iterative one
can start with "for i in range(n):", you will agree that my
terminology is strictly correct. So there.)

ChrisA

[toc] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web