Lambda as declarative idiom (was RE: what is lambda used for in real code?)

Bengt Richter bokr at oz.net
Tue Jan 4 06:46:43 EST 2005


On Mon, 03 Jan 2005 18:54:06 GMT, Steven Bethard <steven.bethard at gmail.com> wrote:

>Roman Suzi wrote:
>> I wish lambdas will not be deprecated in Python but the key to that is
>> dropping the keyword (lambda). If anybody could think of a better syntax for
>> lambdas _with_ arguments, we could develop PEP 312 further.
>
>Some suggestions from recent lambda threads (I only considered the ones 
>that keep lambda as an expression):
>
Just for reference, am I correct in assuming these are the equivalent
uses of lambda?:

 lambda a, b, c:f(a) + o(b) - o(c)
 lambda x: x * x
 lambda : x
 lambda *a, **k: x.bar(*a, **k)
 (lambda : x(*a, **k)) for x, a, k in funcs_and_args_list)

That last seems like it might need the default-arg-value hack: i.e.,
 (lambda x=x, a=a, k=k: x(*a, **k)) for x, a, k in funcs_and_args_list)


>***** Args Before Expression *****
>
>Nick Coghlan: def-to syntax [1]
>(def (a, b, c) to f(a) + o(b) - o(c))
>(def (x) to x * x)
>(def () to x)
>(def (*a, **k) to x.bar(*a, **k))
>((def () to x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>Nick Coghlan: def-arrow syntax [1]
>(def (a, b, c) -> f(a) + o(b) - o(c))
>(def (x) -> x * x)
>(def () -> x)
>(def (*a, **k) -> x.bar(*a, **k))
>((def () -> x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>Alex Martelli: def-as syntax [2]
>(def (a, b, c) as f(a) + o(b) - o(c))
>(def (x) as x * x)
>(def () as x)
>(def (*a, **k) as x.bar(*a, **k))
>((def () as x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>Dave Benjamin: fun syntax [7]
>(fun(a, b, c): f(a) + o(b) - o(c))
>(fun(x): x * x)
>(fun(): x)
>(fun(*a, **k): x.bar(*a, **k))
>((fun(): x(*a, **k)) for x, a, k in funcs_and_args_list)
>
>
>***** Expression Before Args *****
>
>Robert Brewer: for (no-parens) syntax [3]
>(f(a) + o(b) - o(c) for a, b, c)
>(x * x for x)
>(x for ())
>(x.bar(*a, **k) for *a, **k)
>((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)
>
>Nick Coghlan: for syntax [6]
>(f(a) + o(b) - o(c) for (a, b, c))
>(x * x for (x))
>(x for ())
>(x.bar(*a, **k) for (*a, **k))
>((x(*a, **k) for ()) for x, a, k in funcs_and_args_list)
>
>Nick Coghlan: def-from syntax [4]
>(def f(a) + o(b) - o(c) from (a, b, c))
>(def x * x from (x))
>(def x from ())
>(def x.bar(*a, **k) from (*a, **k))
>((def x(*a, **k) from ()) for x, a, k in funcs_and_args_list)
>
>Michael Spencer: from-args syntax [5]
>(f(a) + o(b) - o(c) from args(a, b, c))
>(x * x from args(x))
>(x from args())
>(x.bar(*a, **k) from args(*a, **k))
>((x(*a, **k) from args()) for x, a, k in funcs_and_args_list)
>
>Michael Spencer: for-args syntax [5]
>(f(a) + o(b) - o(c) for args(a, b, c))
>(x * x for args(x))
>(x for args())
>(x.bar(*a, **k) for args(*a, **k))
>((x(*a, **k) for args()) for x, a, k in funcs_and_args_list)
>
>
>So there's a bunch of ideas out there.  I don't know if any of them 
>could be overwhelmingly preferred over lambda.

Just thought of another, more concise and keywordless, expression-before-args syntax:
(:expression)(formalparams)    # equivalent to lambda formalparams:expression

 (:f(a) + o(b) - o(c))(a, b, c)
 (:x*x)(X)
 (:x)()
 (:x.bar(*a, **k))(*a, **k)
 ((:x(*a, **k)() for x, a, k in funcs_and_args_list)
and with args default hack:
 ((:x(*a, **k)(x=x, a=a, k=k) for x, a, k in funcs_and_args_list)

I would have proposed (expression)(formalparams), but that is already legal ;-)


>
>Personally, I lean slightly towards the def-from syntax because it uses 
>the 'def' keyword to bring your attention to the fact that a function is 
>being defined, and it gives the expression precedence over the arglist, 
>which makes sense to me for an anonymous function, where (IMHO) the 
>expression is really the most important part of the declaration.
The syntax above panders to that ;-)

>
>OTOH, I think Michael Spencer's args() function, if implementable, could 
>have a lot of cool uses, like getting the arguments passed to next 
>within a generator.  (See the thread about that[8].)
>
Actually, I would rather have seen the function interface itself used for that, and
not have a scan for yields magically convert the normal function calling interface to
a generator factory interface. But we are past that, unless we invent something new.

E.g. if functions had an f.multicall() factory function that would return a generator
"next" function with the same interface as f but starting code execution at the start
the first time, and after yields on subsequent calls, then we could write

    def f(x):
        yield x+2
        yield x*2
    g = f.multicall()  # not currently available
    [g(n) for n in (2,5)]

and get (untested)
    [4, 10]

instead of as now having to write something like

 >>> def f(x):
 ...     yield x[0]+2
 ...     yield x[0]*2
 ...
 >>> x = ['ignored']
 >>> g = f(x).next
 >>> [g() for x[0] in (2,5)]
 [4, 10]

or wrapping with something more sugary.

>
>Steve
>
>[1]http://mail.python.org/pipermail/python-list/2004-December/256859.html
>[2]http://mail.python.org/pipermail/python-list/2004-December/256881.html
>[3]http://mail.python.org/pipermail/python-list/2004-December/257023.html
>[4]http://boredomandlaziness.skystorm.net/2004/12/anonymous-functions-in-python.html
>[5]http://mail.python.org/pipermail/python-list/2004-December/257893.html
>[6]http://mail.python.org/pipermail/python-list/2004-December/257977.html
>[7]http://mail.python.org/pipermail/python-list/2005-January/258441.html
>[8]http://mail.python.org/pipermail/python-list/2005-January/258238.html

Regards,
Bengt Richter



More information about the Python-list mailing list