Multi-line lambda proposal.

Kaz Kylheku kkylheku at gmail.com
Thu May 11 20:37:33 CEST 2006


Duncan Booth wrote:
> Kaz Kylheku wrote:
>
> > Duncan Booth wrote:
> >> One big problem with this is that with the decorator the function has
> >> a name but with a lambda you have anonymous functions so your
> >> tracebacks are really going to suck.
> >
> > Is this an issue with this particular design that is addressed by
> > other designs?
>
> Yes. Decorators don't interfere with the name of the underlying function
> displayed in tracebacks.

No, I mean do other multi-line lambda design fix this problem somehow?

It looks to me like the programmer's choice, quite simply.

Both programs shown by yairchu at gmail.com use lambda. The first one uses
a decorator to actually define the wrapped function:

  @arg_range(5, 17)
  def f(arg):
    return arg*2

The arg_range function uses a nesting of two lambdas, yet the decorated
function still has a name that nicely shows up in tracebacks.

So in other words, lambdas and decorators play along nicely.

  f = arg_range(5, 17, lambda(arg)):
    return arg*2

Here, the programmer made a decision to define a global function using
an assigment operator instead of def. The underlying function is the
lambda itself. That is not a problem with the multi-line lambda. A
lambda feature is not even required to do create a version of this
problem:

  foo = arg_range(5, 17, bar)

Now the function is called as foo(), but what the programmer sees in
the traceback is "bar", which is potentially confusing.  The traceback
will show that bar() is being called from some given file and line
number, but when that is inspected, there is no bar() there, only an
expression which contains the function call foo() (and possibly other
calls).

I'm only interested in discussing the relative merits of my multi-line
lambda proposal versus others.

I'm not interested in debating people who think that other people who
want multi-line lambdas should not have them.

I also hope that everyone understands that lambdas, multi-line or not,
are not the best tool for every situation for which they are a possible
candidate. I agree with that, and am not interested in debating it
either.  It's off topic to the question of designing that labmda,
except insofar as the design of the lambda influences whether or not
lambda is a good choice in a situation. I.e. "lambda is a bad choice
for this situation if it is designed like this, but not (or less so) if
it is designed like this."

> > Are the existing one-line lambdas free from this problem?
>
> No, but since a single line lambda does virtually nothing it isn't as
> serious. Decorators are useful enough that in some situation you might
> decorate every method in a class (e.g. for a web application you might
> apply security settings with decorators). In that situation you have just
> messed up every stack frame in every traceback.

The problem there is that the programmer uses anonymous functions for
class methods, rather than decorating named class methods. (Are
anonymous class methods even possible? Lambdas can take an object as
their first argument, but that's not the same thing.)

> I end up reading tracebacks quite a lot, and it is the sequence of the function
> names which matter first, I don't usually need to go and look at the file
> and code lines.
> >
> > Let me make the observation that  name of an inner function is, alone,
> > insufficient to identify that function in a debugging scenario. If you
> > have some inner function called I, defined within function F, you need
> > to know that it's the I inside F, and not some other I.
> >
> If the stack frame shows I called from F then it is usually a pretty good
> guess that it means the I inside F.

"Pretty good guess" doesn't cut it. Fact is, that the identities of
these functions are not unambiguously pinned down by their name alone;
moreover, the line number and file information alone actually does
precisely pinpoint the location of the exception.

If only the names of functions appeared in the traceback, it would be
less useful. If foo calls bar in three different places, you would not
know which of those three places is responsible for the call of bar
from foo. Moreover, in the bottom-most frame, you would not know which
line in the function actually triggered the traceback.

So I do not believe your claim that you rarely need to look at the line
number information when comprehending tracebacks.




More information about the Python-list mailing list