Multi-line lambda proposal.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Duncan Booth

    #16
    Re: Multi-line lambda proposal.

    yairchu@gmail.c om wrote:
    [color=blue]
    > this is how I think it should be done with multi-line lambdas:
    >
    > def arg_range(inf, sup, f):
    > return lambda(arg):
    > if inf <= arg <= sup:
    > return f(arg)
    > else:
    > raise ValueError
    >
    > and instead of
    > @arg_range(5, 17)
    > def f(arg):
    > return arg*2
    >
    > you do:
    > f = arg_range(5, 17, lambda(arg)):
    > return arg*2
    >
    >[/color]
    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.

    Comment

    • Sybren Stuvel

      #17
      Re: Multi-line lambda proposal.

      yairchu@gmail.c om enlightened us with:[color=blue]
      > this is how I think it should be done with multi-line lambdas:
      >
      > def arg_range(inf, sup, f):
      > return lambda(arg):
      > if inf <= arg <= sup:
      > return f(arg)
      > else:
      > raise ValueError[/color]

      This is going to be fun to debug if anything goes wrong. Ever seen
      such a traceback?
      [color=blue]
      > and instead of
      > @arg_range(5, 17)
      > def f(arg):
      > return arg*2
      >
      > you do:
      > f = arg_range(5, 17, lambda(arg)):
      > return arg*2[/color]

      A function decorator is supposed to add something to a function. The
      syntax that sticks the closest to that of defining a function seems
      most Pythonic to me.

      I can already foresee that I'll have a tougher time explaining your
      lambda-based "decorators ", than the current decorators, to people
      learning Python.

      Sybren
      --
      The problem with the world is stupidity. Not saying there should be a
      capital punishment for stupidity, but why don't we just take the
      safety labels off of everything and let the problem solve itself?
      Frank Zappa

      Comment

      • Kaz Kylheku

        #18
        Re: Multi-line lambda proposal.

        Duncan Booth wrote:[color=blue]
        > 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.[/color]

        Is this an issue with this particular design that is addressed by other
        designs?

        Are the existing one-line lambdas free from this problem?

        Is there really a problem? The Python tracebacks identify every frame
        by file and line number, as well as name, if one is available.

        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.

        Look at what happens with:
        [color=blue][color=green][color=darkred]
        >>> def err():[/color][/color][/color]
        .... def inner():
        .... return nonexistent
        .... return inner
        ....[color=blue][color=green][color=darkred]
        >>> err()[/color][/color][/color]
        <function inner at 0x8177304>[color=blue][color=green][color=darkred]
        >>> err()()[/color][/color][/color]
        Traceback (most recent call last):
        File "<stdin>", line 1, in ?
        File "<stdin>", line 3, in inner
        NameError: global name 'nonexistent' is not defined

        In the traceback, the programmer is told that the error occured in a
        function called inner. However, there could be many functions called
        inner, including a global one. The programmer is not told that it's the
        function inner which is defined inside the function err, which could be
        done with some qualified name syntax like err.inner or whatever. So
        this piece of information is about as useful as being told that it was
        inside a lambda.

        The real key which lets the programmer correlate the error back to the
        source code is the file name and line number. When he locates that line
        of code, then it's obvious---aha---it is in the middle of an inner
        function called "inner", which also happens to be inside a global
        function called "err".

        Comment

        • Kaz Kylheku

          #19
          Re: Multi-line lambda proposal.

          Sybren Stuvel wrote:[color=blue]
          > yairchu@gmail.c om enlightened us with:[color=green]
          > > this is how I think it should be done with multi-line lambdas:
          > >
          > > def arg_range(inf, sup, f):
          > > return lambda(arg):
          > > if inf <= arg <= sup:
          > > return f(arg)
          > > else:
          > > raise ValueError[/color]
          >
          > This is going to be fun to debug if anything goes wrong. Ever seen
          > such a traceback?[/color]

          I'm looking at various tracebacks now. I don't see any special problems
          with lambdas. Inner functions are inadequately identified, so that the
          file and line number has to be used, which works just as well as for
          lambdas.
          [color=blue]
          > A function decorator is supposed to add something to a function. The
          > syntax that sticks the closest to that of defining a function seems
          > most Pythonic to me.[/color]

          Which proposed lambda syntax is closest in this sense?
          [color=blue]
          > I can already foresee that I'll have a tougher time explaining your
          > lambda-based "decorators ", than the current decorators, to people
          > learning Python.[/color]

          Is it unusual to have a tougher time explaining X than Y to people who
          are learning a language, where X and Y are different features?

          For instance, an assignment statement is easier to explain than a
          metaclass. Therefore, assignment statements are probably going to be
          covered in an earlier lecture of a Python course than metaclasses.

          In what language are features equally easy to explain?

          It's possible to use Python while pretending that lambdas don't exist
          at all. (That's true of the lambda in its current form, as well as the
          proposed forms).

          Comment

          • Duncan Booth

            #20
            Re: Multi-line lambda proposal.

            Kaz Kylheku wrote:
            [color=blue]
            > Duncan Booth wrote:[color=green]
            >> 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.[/color]
            >
            > Is this an issue with this particular design that is addressed by
            > other designs?[/color]

            Yes. Decorators don't interfere with the name of the underlying function
            displayed in tracebacks.
            [color=blue]
            >
            > Are the existing one-line lambdas free from this problem?[/color]

            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.[color=blue]
            >
            > Is there really a problem? The Python tracebacks identify every frame
            > by file and line number, as well as name, if one is available.[/color]

            Great, and I suppose that if they printed out the line numbers in binary
            that wouldn't make it harder to understand the traceback either. 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.
            [color=blue]
            >
            > 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.
            >[/color]
            If the stack frame shows I called from F then it is usually a pretty good
            guess that it means the I inside F. Besides, I don't usually name all my
            inner functions I; I find that giving them meaningful names tends to help.

            Comment

            • Terry Reedy

              #21
              Re: Multi-line lambda proposal.


              "Kaz Kylheku" <kkylheku@gmail .com> wrote in message
              news:1147366331 .637492.129980@ i39g2000cwa.goo glegroups.com.. .[color=blue]
              > 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.
              >
              > Look at what happens with:
              >[color=green][color=darkred]
              >>>> def err():[/color][/color]
              > ... def inner():
              > ... return nonexistent
              > ... return inner
              > ...[color=green][color=darkred]
              >>>> err()[/color][/color]
              > <function inner at 0x8177304>[color=green][color=darkred]
              >>>> err()()[/color][/color]
              > Traceback (most recent call last):
              > File "<stdin>", line 1, in ?
              > File "<stdin>", line 3, in inner
              > NameError: global name 'nonexistent' is not defined[/color]

              So name it err_inner. Or _err.

              tjr



              Comment

              • Kaz Kylheku

                #22
                Re: Multi-line lambda proposal.

                Terry Reedy wrote:[color=blue]
                > So name it err_inner. Or _err.[/color]

                Right. The C language approach to namespaces.

                Comment

                • Kaz Kylheku

                  #23
                  Re: Multi-line lambda proposal.

                  Duncan Booth wrote:[color=blue]
                  > Kaz Kylheku wrote:
                  >[color=green]
                  > > Duncan Booth wrote:[color=darkred]
                  > >> 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.[/color]
                  > >
                  > > Is this an issue with this particular design that is addressed by
                  > > other designs?[/color]
                  >
                  > Yes. Decorators don't interfere with the name of the underlying function
                  > displayed in tracebacks.[/color]

                  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@gmail.c om 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."
                  [color=blue][color=green]
                  > > Are the existing one-line lambdas free from this problem?[/color]
                  >
                  > 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.[/color]

                  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.)
                  [color=blue]
                  > 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.[color=green]
                  > >
                  > > 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.
                  > >[/color]
                  > If the stack frame shows I called from F then it is usually a pretty good
                  > guess that it means the I inside F.[/color]

                  "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.

                  Comment

                  • Sybren Stuvel

                    #24
                    Re: Multi-line lambda proposal.

                    Kaz Kylheku enlightened us with:[color=blue]
                    > Which proposed lambda syntax is closest in this sense?[/color]

                    I was talking about different ways (your multi-line lambda vs. the
                    currently implemented one) of doing function decorators.
                    [color=blue]
                    > Is it unusual to have a tougher time explaining X than Y to people
                    > who are learning a language, where X and Y are different features?[/color]

                    See above: same feature, function decorators.

                    Sybren
                    --
                    The problem with the world is stupidity. Not saying there should be a
                    capital punishment for stupidity, but why don't we just take the
                    safety labels off of everything and let the problem solve itself?
                    Frank Zappa

                    Comment

                    Working...