A replacement for lambda

Bengt Richter bokr at oz.net
Sat Jul 30 22:45:17 CEST 2005

On Fri, 29 Jul 2005 18:07:31 -0400, Mike Meyer <mwm at mired.org> wrote:

>I know, lambda bashing (and defending) in the group is one of the most
>popular ways to avoid writing code. However, while staring at some Oz
>code, I noticed a feature that would seem to make both groups happy -
>if we can figure out how to avoid the ugly syntax.
>This proposal does away with the well-known/obscure "lambda"
>keyword. It gives those who want a more functional lambda what they
>want. It doesn't add any new keywords. It doesn't add any new magic
>characters, though it does add meaning to an existing one. That could
>be replaced by a new magic token, or adding magic meaning to a
>non-magic token. It breaks no old code either way.
>I haven't really worked out all the implications; I just wanted to
>throw it out and see what everyone else thought about it. As a
>result, the code examples tend to be ugly.
>As previously hinted, this feature is lifted from Oz.
>Currently, class and functions definitions consist of a keyword -
>either "class" or "def" - followed by a name, a header, then code. The
>code is compiled into an object, and the name is bound to that object.
>The proposal is to allow name to be a non-name (or rare name)
>token. In this case, the code is compiled and the resulting object is
>used as the value of the class/def expression.
>My choice for the non-name token is "@". It's already got magic
>powers, so we'll give it more rather than introducing another token
>with magic powers, as the lesser of two evils.
>Rewriting a canonical abuse of lambda in this idiom gives:
>myfunc = def @(*args):
>             return sum(x + 1 for x in args)

If you remove the '@' -- which is not really needed -- you have exactly my (at least
I think it was mine -- the variation are, in any case ;-) old anonymous def proposal.

So good luck in getting any more favorable attention than I did ;-)
I've also proposed named and anonymous callable local blocks for
the other variations of removing 'def' and/or the binding name from
normal def syntax. E.g.,

    def my_func(*args):                # normal def
              return sum(x + 1 for x in args)

    my_func = def(*args):              # anonymous def expression
              return sum(x + 1 for x in args)

    my_local_callable_block(*args):    # named local callable block
              nargs = len(args)   # binds nargs as if this suite were e.g. an "if" suite.
              return sum(x + 1 for x in args)

    my_local_callable_block = (*args): # local callable block expression
              nargs = len(args)   # binds nargs as if this suite were e.g. an "if" suite.
              return sum(x + 1 for x in args)

The local callable blocks can be made accessible via a dict or list or whatever and called like

to have the bindings occur in the scope of the block definition. This avoids the problem of
the typical case dispatch of function calls via a dict, where the function has its own temporary
local namespace and binding in the calling namespace is kludgey.

>In other words, this is identical to:
>def myfunc(*args):
>    return sum(x + 1 for x in args)
>We can write the same loop with logging information as:
>sum(def @(arg):
>        print "Bumping", arg
>        return arg + 1
>    (x)           # '(' at the same indent level as def, to end the definition
>    for x in stuff)

You are almost quoting me in previous posts (protesting that the indentation "problem" is no big deal ;-)

>A more useful example is the ever-popular property creation without
>cluttering the class namespace:
>class Spam(object):
>      myprop = property(fget = def @(self):
>                                   return self._properties['myprop']
>                               ,
>                        fset = def @(self, value):
>                                   self._properties['myprop'] = value
>                               ,
>                        fdel = def @(self)
>                                   del self._properties['myprop']
>                               ,
>                        doc = "Just an example")
Again, the '@' is not necessary ;-)

>This looks like the abuse of lambda case, but these aren't
>assignments, they're keyword arguments. You could leave off the
>keywords, but it's not noticably prettier. fget can be done with a
>lambda, but the the others can't.
Well, they can, but it's not pretty ;-)

>Giving clases the same functionality seems to be the reasonable thing
>to do. It's symmetric. And if anonymous function objects are good,
>then anonymous class objects ought to be good as well.
I agree.

Bengt Richter

More information about the Python-list mailing list