Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

inner methods and recursion

3 views
Skip to first unread message

Steve Howell

unread,
Jan 18, 2010, 5:00:17 PM1/18/10
to
Hi, I have a style/design question relating to recursion and inner
methods.

I wrote some code recently that implements a recursive algorithm that
takes several parameters from the original caller. Once the algorithm
starts running and recursing, those parameters remain the same, so I
define an inner method called "recurse" that essentially curries those
parameters. In particular, the recurse method can get passed to a
callback method that the caller supplies, so that the caller can wrap
the recursive step with their own logic.

The only thing I don't like about the technique that I'm using is that
it seems needlessly repetitive to define mostly the same parameter
list in two different places. The repetition seems mostly harmless,
but it seems like some kind of a smell that I'm overlooking a simpler
way to write the code. I just can't put my finger on what it is.

def indent_lines(lines,
branch_method,
leaf_method,
pass_syntax,
flush_left_syntax,
flush_left_empty_line,
indentation_method,
get_block,
):
def recurse(lines):
return indent_lines(
lines,
branch_method,
leaf_method,
pass_syntax,
flush_left_syntax,
flush_left_empty_line,
indentation_method,
get_block,
)
output = []
while lines:
if lines[0].strip() == '':
lines.pop(0)
output.append('')
else:
prefix, i = get_block(lines, indentation_method)
if i == 1:
line = lines.pop(0)[len(prefix):]
if line == pass_syntax:
pass
elif line.startswith(flush_left_syntax):
output.append(line[len(flush_left_syntax):])
elif line.startswith(flush_left_empty_line):
output.append('')
else:
output.append(prefix + leaf_method(line))
else:
block = lines[:i]
lines = lines[i:]
output += branch_method(prefix, block, recurse)
return output

Does anybody have any inspiration here? I vaguely recall a discussion
some time back about having some kind of @recursive decorator, but I
can't seem to find the thread.

Gabriel Genellina

unread,
Jan 18, 2010, 9:07:11 PM1/18/10
to pytho...@python.org
En Mon, 18 Jan 2010 19:00:17 -0300, Steve Howell <show...@yahoo.com>
escribi�:

> Hi, I have a style/design question relating to recursion and inner
> methods.
>
> I wrote some code recently that implements a recursive algorithm that
> takes several parameters from the original caller. Once the algorithm
> starts running and recursing, those parameters remain the same, so I
> define an inner method called "recurse" that essentially curries those
> parameters. In particular, the recurse method can get passed to a
> callback method that the caller supplies, so that the caller can wrap
> the recursive step with their own logic.

Python already have lexical scoping, you can take advantage of it. On any

non-prehistoric version of Python you may write:


def indent_lines(lines,
branch_method,
leaf_method,
pass_syntax,
flush_left_syntax,
flush_left_empty_line,
indentation_method,
get_block,
):

def _indent_lines(lines):
output = []
while lines:
# ... the real work ...
# recursive call:
output += branch_method(prefix, block, _indent_lines)
return output

return _indent_lines(lines)

The real work happens inside _indent_lines, and it has access to the outer
indent_lines scope, where all remaining parameters are defined.

> The only thing I don't like about the technique that I'm using is that
> it seems needlessly repetitive to define mostly the same parameter
> list in two different places. The repetition seems mostly harmless,
> but it seems like some kind of a smell that I'm overlooking a simpler
> way to write the code. I just can't put my finger on what it is.

Is the above technique what you were looking for?

> Does anybody have any inspiration here? I vaguely recall a discussion
> some time back about having some kind of @recursive decorator, but I
> can't seem to find the thread.

The thread I remember was about making "true" recursive calls (normal
recursive calls at global or method scope are not truly recursive: they
actually perform a name lookup, which may or may not yield the original
function). In the above case, that doesn't happen, the recursive call
resolves the _indent_lines name directly using a cell "pointing" into its
container local scope.

--
Gabriel Genellina

Steve Howell

unread,
Jan 18, 2010, 9:55:58 PM1/18/10
to
On Jan 18, 6:07 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
> En Mon, 18 Jan 2010 19:00:17 -0300, Steve Howell <showel...@yahoo.com>  
> escribió:

That was exactly what I was looking for. I just tried it out, and it
works perfectly. Thanks!

0 new messages