A replacement for lambda

Bengt Richter bokr at oz.net
Sat Jul 30 16:45:17 EDT 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
    
    lcb_dict[key](args)

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.

Regards,
Bengt Richter



More information about the Python-list mailing list