Replacement for lambda - 'def' as an expression?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • talin at acm dot org

    #1

    Replacement for lambda - 'def' as an expression?

    I've been reading about how "lambda" is going away in Python 3000 (or
    at least, that's the stated intent), and while I agree for the most
    part with the reasoning, at the same time I'd be sad to see the notion
    of "anonymous functions" go - partly because I use them all the time.

    Of course, one can always create a named function. But there are a lot
    of cases, such as multimethods / generics and other scenarios where
    functions are treated as data, where you have a whole lot of functions
    and it can be tedious to come up with a name for each one.

    For example, my current hobby project is implementing pattern matching
    similar to Prolog in Python. The dispatcher I am making allows you to
    create "overloaded " versions of a function that take different patterns
    as their input arguments, so that Simplify( (add, x, y) ) calls a
    different method than Simplify( (log, x) ) -- in other words, the
    choice of which code is executed is based on the structure of the tuple
    that is passed into it. However, in order for this to work, I need to
    be able to assign a block of Python code to a particular pattern, and
    having to invent a named function for each pattern is a burden :)

    Anyway, here's an example, then, of how 'def' could be used:

    add = def( a, b ):
    return a + b

    The lack of a function name signals that this is an anonymous function.
    The def keyword defines the function using the same syntax as always -
    the arguments are in parentheses, and are unevaluated; The colon marks
    the beginning of a suite.

    In fact, it looks a lot like the existing lambda, with a couple of
    differences:

    1) It uses the familiar "def" keyword, which every Python beginner
    understands, instead of the somewhat unfamiliar "lambda"
    2) The arguments are enclosed in parentheses, instead of a bare tuple
    followed by a colon, again reiterating the similarity to the normal
    usage of "def".
    3) The statements are a real suite instead of a pseudo-suite - they can
    consist of multiple lines of statements.

    Like all statements whose last argument is a suite, you can put the
    body of the function on a single line:

    add = def( a, b ): return a + b

    (If this were Perl, you could also omit the "return", since in Perl the
    last evaluated expression in the function body is what gets returned if
    there's no explicit return statement.)

    What about passing an anonymous function as an argument, which is the
    most common case? This gets tricky, because you can't embed a suite
    inside of an expression. Or can you?

    The most powerful option would be to leverage the fact that you can
    already do line breaks inside of parentheses. So the "def" keyword
    would tell the parser to restart the normal indentation calculations,
    which would terminate whenever an unmatched brace or paren was
    encountered:

    a = map(
    (def( item ):
    item = do_some_calcula tion( item )
    return item
    ), list )

    The one-liner version looks a lot prettier of course:

    a = map( (def( item ): return item * item), list )

    And it looks even nicer if we switch the order of the arguments around,
    since you can now use the final paren of the enclosing function call to
    terminate the def suite.

    a = map( list, def( item ): return item * item )

    Unfortunately, there's no other good way I can think of to signal the
    end of the block of statements without introducing some radical new
    language construct.

    (Besides, if being an expression is good enough for 'yield', why
    shouldn't def get the same privilege? :)

  • Torsten Bronger

    #2
    Re: Replacement for lambda - 'def' as an expression?

    Hallöchen!

    "talin at acm dot org" <viridia@gmail. com> writes:
    [color=blue]
    > [...]
    >
    > Anyway, here's an example, then, of how 'def' could be used:
    >
    > add = def( a, b ):
    > return a + b[/color]

    I'm really not an expert in functional programming, so I wonder
    what's the difference between "add = def" (assumed that it worked)
    and "def add"?

    Tschö,
    Torsten.

    --
    Torsten Bronger, aquisgrana, europa vetus ICQ 264-296-646

    Comment

    • Guest's Avatar

      #3
      Re: Replacement for lambda - 'def' as an expression?

      On Tue, 06 Sep 2005 12:19:21 +0200
      Torsten Bronger wrote:
      [color=blue]
      > "talin at acm dot org" <viridia@gmail. com> writes:[color=green]
      > > Anyway, here's an example, then, of how 'def' could be used:
      > >
      > > add = def( a, b ):
      > > return a + b[/color]
      >
      > I'm really not an expert in functional programming, so I wonder
      > what's the difference between "add = def" (assumed that it worked)
      > and "def add"?[/color]

      In the former case one could write

      self.add[0] = def(a, b)
      # etc.

      --
      jk

      Comment

      • Sybren Stuvel

        #4
        Re: Replacement for lambda - 'def' as an expression?

        talin at acm dot org enlightened us with:[color=blue]
        > I'd be sad to see the notion of "anonymous functions" go[/color]

        Same here. I think it's a beautyful concept, and very powerful. It
        also allows for dynamic function creation in cases where a name would
        not be available.
        [color=blue]
        > What about passing an anonymous function as an argument, which is
        > the most common case?[/color]

        I don't really like that. The syntax is way too messy. Just the

        funcref = def(args):
        ...

        syntax would suffice for me.

        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

        • Rocco Moretti

          #5
          Re: Replacement for lambda - 'def' as an expression?

          en.karpachov@os paz.ru wrote:[color=blue]
          > On Tue, 06 Sep 2005 12:19:21 +0200
          > Torsten Bronger wrote:
          >
          >[color=green]
          >>"talin at acm dot org" <viridia@gmail. com> writes:
          >>[color=darkred]
          >>>Anyway, here's an example, then, of how 'def' could be used:
          >>>
          >>>add = def( a, b ):
          >>> return a + b[/color]
          >>
          >>I'm really not an expert in functional programming, so I wonder
          >>what's the difference between "add = def" (assumed that it worked)
          >>and "def add"?[/color]
          >
          >
          > In the former case one could write
          >
          > self.add[0] = def(a, b)
          > # etc.[/color]

          If that's the issue, it might make more sense to extend def to take any
          lvalue.

          def self.add[0](a, b):
          return a + b

          Comment

          • Leif K-Brooks

            #6
            Re: Replacement for lambda - 'def' as an expression?

            Sybren Stuvel wrote:[color=blue]
            > It also allows for dynamic function creation in cases where a name
            > would not be available.[/color]

            What cases are those?

            Comment

            • Sybren Stuvel

              #7
              Re: Replacement for lambda - 'def' as an expression?

              Leif K-Brooks enlightened us with:[color=blue][color=green]
              >> It also allows for dynamic function creation in cases where a name
              >> would not be available.[/color]
              >
              > What cases are those?[/color]

              An example:

              def generate_random izer(n, m):
              randomizer = def(x):
              return x ** n % m

              return randomizer

              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

              • Paul Rubin

                #8
                Re: Replacement for lambda - 'def' as an expression?

                Sybren Stuvel <sybrenUSE@YOUR thirdtower.com. imagination> writes:[color=blue]
                > An example:
                >
                > def generate_random izer(n, m):
                > randomizer = def(x):
                > return x ** n % m
                >
                > return randomizer[/color]

                You're a little bit confused; "name" doesn't necessarily mean "persistent
                name". You could write the above as:

                def generate_random izer (n, m):
                def randomizer(x):
                return pow(x, n, m)
                return randomizer

                Comment

                • D H

                  #9
                  Re: Replacement for lambda - 'def' as an expression?

                  talin at acm dot org wrote:[color=blue]
                  > I've been reading about how "lambda" is going away in Python 3000 (or[/color]

                  See the page built from earlier threads about this:


                  Your syntax is the same used in boo: http://boo.codehaus.org/Closures

                  Comment

                  • Terry Reedy

                    #10
                    Re: Replacement for lambda - 'def' as an expression?


                    "talin at acm dot org" <viridia@gmail. com> wrote in message
                    news:1125996559 .130055.154400@ z14g2000cwz.goo glegroups.com.. .[color=blue]
                    > Of course, one can always create a named function. But there are a lot
                    > of cases, such as multimethods / generics and other scenarios where
                    > functions are treated as data, where you have a whole lot of functions
                    > and it can be tedious to come up with a name for each one.[/color]

                    Either reuse names or 'index' them: f0, f1, f2, ...
                    [color=blue]
                    > add = def( a, b ):
                    > return a + b[/color]

                    The difference between this and def add(a,b): return a+b would be the
                    finding of .func_name to an uninformative generic tag (like '<lambda.>')
                    versus the informative 'add'.
                    [color=blue]
                    >I need to be able to assign a block of Python code to a particular
                    >pattern,[/color]

                    How about (untested -- I have never actually written a decorator, and am
                    following a remembered pattern of parameterized decorators) :

                    patcode = {}
                    def pat(pattern): # return decorator that registers f in patcode
                    def freg(f):
                    f.func_name = 'pat: <%s>' % pattern # optional but useful for debug
                    patcode[pattern] = f
                    # no return needed ? since def name is dummy
                    return freg

                    @pat('pattern1' )
                    def f(): <code for pattern 1>

                    @pat('pattern2' )
                    def f(): <code> for pattern 2>

                    etc

                    or define freg(f,pat) and call freg *after* each definition
                    [color=blue]
                    > having to invent a named function for each pattern is a burden :)[/color]

                    But you do not *have to* ;-)
                    or rather, you can replace func_name with a useful tag as suggested above.

                    Terry J. Reedy






                    Comment

                    • Terry Reedy

                      #11
                      Re: Replacement for lambda - 'def' as an expression?


                      "Sybren Stuvel" <sybrenUSE@YOUR thirdtower.com. imagination> wrote in message
                      news:slrndhr3q6 .48f.sybrenUSE@ schuimige.unrea ltower.org...[color=blue]
                      > talin at acm dot org enlightened us with:[color=green]
                      >> I'd be sad to see the notion of "anonymous functions" go[/color][/color]

                      Though it is as yet unclear as to what may come in compensation.
                      [color=blue]
                      > Same here. I think it's a beautyful concept[/color]

                      Are you claiming that including a reference to the more humanly readable
                      representation of a function (its source code) somehow detracts from the
                      beauty of the function concept? Or are you claiming that binding a
                      function to a name rather than some other access reference (like a list
                      slot) somehow detracts from its conceptual beauty? Is so, would you say
                      the same about numbers?

                      It seems to me that the beauty of the function concept is quite independent
                      of its definition syntax and post-definition access method.
                      [color=blue]
                      >, and very powerful.[/color]

                      If anything, adding a source pointer to a function object makes it more,
                      not less powerful.
                      [color=blue][color=green]
                      >> What about passing an anonymous function as an argument,
                      >> which is the most common case?[/color]
                      >
                      > I don't really like that. The syntax is way too messy.[/color]

                      I agree.
                      [color=blue]
                      > Just the
                      > funcref = def(args):
                      > ...
                      > syntax would suffice for me.[/color]

                      But this is deficient relative to def funcref(args): ... since the *only*
                      difference is to substitute a generic tag (like '<lambda>') for a specific
                      tag (like 'funcref') for the .func_name attribute.

                      Terry J. Reedy




                      Comment

                      • Sybren Stuvel

                        #12
                        Re: Replacement for lambda - 'def' as an expression?

                        Paul Rubin enlightened us with:[color=blue]
                        > You're a little bit confused; "name" doesn't necessarily mean
                        > "persistent name".[/color]

                        Wonderful. Another feature added to Python (that is: the Python
                        version in my mind ;-) without the need to add any features to Python
                        (that is: the real Python)

                        Thanks!

                        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

                        • Sybren Stuvel

                          #13
                          Re: Replacement for lambda - 'def' as an expression?

                          Terry Reedy enlightened us with:[color=blue]
                          > Are you claiming that including a reference to the more humanly readable
                          > representation of a function (its source code) somehow detracts from the
                          > beauty of the function concept?[/color]

                          Nope.
                          [color=blue]
                          > Or are you claiming that binding a function to a name rather than
                          > some other access reference (like a list slot) somehow detracts from
                          > its conceptual beauty?[/color]

                          Nope.
                          [color=blue]
                          > Is so, would you say the same about numbers?[/color]

                          Nope.

                          I was under the (apparently very wrong) impression (don't ask my why)
                          that something like the example that Paul Rubin gave wouldn't be
                          possible. Now that I've learned that, I take back what I've said. His
                          code is more beautyful IMO ;-)

                          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

                          • talin at acm dot org

                            #14
                            Re: Replacement for lambda - 'def' as an expression?

                            I like the decorator idea. Unfortunately, the version of Python I am
                            using is pre-decorator, and there are various issues involved in
                            upgrading on Mac OS X (due to the built-in Python 2.3 being used by the
                            OS itself.) I'll have to look into how to upgrade without breaking too
                            much...

                            Some further examples of what I am trying to do. First let me state
                            what my general goal is: There are lots of inference engines out there,
                            from Prolog to Yacas, but most of them rely on a custom interpreter.
                            What I want to find out is if I can build a solver, not by creating a
                            new language on top of Python, but rather by giving solver-like
                            capabilities to a Python programmer. Needless to say, this involves a
                            number of interesting hacks, and part of the motivation for my
                            suggestion(s) is reducing the hack factor.

                            So, at the risk of being visited by Social Services for my abuse of
                            Python Operators, here's a sample of how the sovler works:

                            # Define a function with multiple arities
                            Simplify = Function()

                            # Define some arities. We overload __setitem__ to define an arity.
                            # Param is a class who'se metaclass defines __getattr__ to return a new
                            instance
                            # of Param with the given parameter name.
                            Simplify[ ( add, Param.x, 0 ) ] = lamba x: return Simplify( x ) # x
                            + 0 = x
                            Simplify[ ( mul, Param.x, 1 ) ] = lamba x: return Simplify( x ) # x
                            * 1 = x
                            Simplify[ ( mul, Param.x, 0 ) ] = lamba x: return 0 #
                            x * 0 = 0
                            Simplify[ Param.x ] = lamba x: return x
                            # Fallback case

                            # Invoke the function. Should print the value of x
                            print Simplify( (add, x, 0) )

                            Of course, what I really want is not def or lambda, what I really want
                            is to be able to define functions that take suites as arguments. But
                            that would be crazy talk :)

                            Define( "Simplify", args ):
                            code

                            Comment

                            • Robert Kern

                              #15
                              Re: Replacement for lambda - 'def' as an expression?

                              talin at acm dot org wrote:[color=blue]
                              > I like the decorator idea. Unfortunately, the version of Python I am
                              > using is pre-decorator, and there are various issues involved in
                              > upgrading on Mac OS X (due to the built-in Python 2.3 being used by the
                              > OS itself.) I'll have to look into how to upgrade without breaking too
                              > much...[/color]

                              There really aren't any issues. The official 2.4.1 binary installs
                              alongside the built-in 2.3. The executables python{,w,2.4,w 2.4} are
                              installed the /usr/local/bin . Under no circumstances should you have to
                              replace the built-in 2.3. Indeed, under no circumstances should you
                              replace it at all.

                              --
                              Robert Kern
                              rkern@ucsd.edu

                              "In the fields of hell where the grass grows high
                              Are the graves of dreams allowed to die."
                              -- Richard Harter

                              Comment

                              Working...