A replacement for lambda

Mike Meyer mwm at mired.org
Fri Jul 29 18:07:31 EDT 2005


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)

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)

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

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.

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.

     <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list