Securing a future for anonymous functions in Python

Bengt Richter bokr at oz.net
Thu Dec 30 17:08:37 EST 2004


On Thu, 30 Dec 2004 23:28:46 +1000, Nick Coghlan <ncoghlan at iinet.net.au> wrote:

>GvR has commented that he want to get rid of the lambda keyword for Python 3.0. 
>Getting rid of lambda seems like a worthy goal, but I'd prefer to see it dropped 
>in favour of a different syntax, rather than completely losing the ability to 
>have anonymous functions.
>
>Anyway, I'm looking for feedback on a def-based syntax that came up in a recent 
>c.l.p discussion:
>http://boredomandlaziness.skystorm.net/2004/12/anonymous-functions-in-python.html
>
Nit: You didn't try the code you posted ;-)

 >>> funcs = [(lambda x: x + i) for i in range(10)]
 >>>
 >>> def incrementors():
 ...   for i in range(10):
 ...     def incrementor(x):
 ...       return x + i
 ...     yield incrementor
 ...
 >>> #funcs = list(incrementors)
 ... funcs2 = list(incrementors())
 >>>
 >>> for f in funcs: print f(0),
 ...
 9 9 9 9 9 9 9 9 9 9
 >>> for f in funcs2: print f(0),
 ...
 9 9 9 9 9 9 9 9 9 9

This is an easy trap to fall into, so if the new lambda-substitute could
provide a prettier current-closure-variable-value capture than passing a dummy default
value or nesting another def and passing the value in, to provide a private closure for each,
that might be something to think about.

IMO an anonymous def that exactly duplicates ordinary def except for leaving out
the function name and having a local indentation context would maximize flexibility
and also re-use of compiler code. People could abuse it, but that's already true
of many Python features.

>From your web page:
----
def either(condition, true_case, false_case):
  if condition:
    return true_case()
  else:
    return false_case()

print either(A == B, (def "A equals B"), (def "A does not equal B"))
either(thefile, (def thefile.close()), (def 0))
----

I'd rather see (:something) than (def something) for this special case,
but the full-fledged anonymous def would spell it thus:

print either(A == B, (def():return "A equals B"), (def(): return "A does not equal B"))
either(thefile, (def(): return thefile.close()), (def(): return 0))

BTW,

    funcs = [(lambda x: x + i) for i in range(10)]

might be spelled

    funcs = [(def(x, i=i): return x + i) for i in range(10)]

or optionally

    funcs = [(
        def(x, i=i):
            return x + i
        ) for i in range(10)]

or

    funcs = [(def(x, i=i):
                  return x + i) for i in range(10)]
or
    funcs = [(def(x, i=i):
                  return x + i)
        for i in range(10)]
or
    funcs = [def(x, i=i):
                 return x + i
             for i in range(10)]
or
    funcs = [
        def(x, i=i):
            return x + i
        for i in range(10)]

and so on. (the def defines the indentation base if the suite is indented, and the closing ')'
terminates the anonymous def explicitly, or a dedent to the level of the def or less can do it,
as in the last two examples).

This one

    (def f(a) + g(b) - h(c) from (a, b, c))

would be spelled (if I undestand your example)

    (def(a, b, c): return f(a)+g(b)+h(c))

which seems to me familiar and easy to understand.

BTW, there are old threads where this and other formats were discussed. I am still
partial to the full anonymous def with nesting indentation rules. Syntactic sugar
could be provided for useful abbreviations (that could possibly be expanded by the
tokenizer -- re which possibilities I haven't seen any discussion than my own
recent post, BTW), but I'd like the full capability.

Regards,
Bengt Richter



More information about the Python-list mailing list