diff --git a/pep-0312.txt b/pep-0312.txt new file mode 100644 index 000000000..28c476c99 --- /dev/null +++ b/pep-0312.txt @@ -0,0 +1,159 @@ +PEP: 312 +Title: Simple Implicit Lambda +Version: $Revision$ +Last-Modified: $Date$ +Author: Roman Suzi , Alex Martelli +Status: Draft +Type: Standards Track +Content-Type: text/plain +Created: 11-Feb-2003 +Python-Version: 2.4 +Post-History: + +Abstract + + This PEP proposes to make argumentless lambda keyword optional in + some cases where it is not grammatically ambiguous. + +Motivation + + Lambdas are useful for defining anonymous functions, e.g. for use + as callbacks or (pseudo)-lazy evaluation schemes. Often, lambdas + are not used when they would be appropriate, just because the keyword + "lambda" makes code look complex. Omitting lambda in some special + cases is possible, with small and backwards compatible changes to + the grammar, and provides a cheap cure against such "lambdaphobia". + +Rationale + + Sometimes people do not use lambdas because they fear to introduce + a term with a theory behind it. This proposal makes introducing + argumentless lambdas easier, by omitting the "lambda" keyword. + itself. Implementation can be done simply changing grammar so it + lets the "lambda" keyword be implied in a few well-known cases. + In particular, adding surrounding brackets lets you specify nullary + lambda anywhere. + +Syntax + + An argumentless "lambda" keyword can be omitted in the following cases: + + * immediately after "=" in named parameter assignment or default value + assignment; + + * immediately after "(" in any expression; + + * immediately after a "," in a function argument list; + + * immediately after a ":" in a dictionary literal; (not implemented) + + * in an assignment statement; (not implemented) + +Examples of Use + + 1) Inline "if": + + def ifelse(cond, true_part, false_part): + if cond: + return true_part() + else: + return false_part() + + # old syntax: + print ifelse(a < b, lambda:A, lambda:B) + + # new syntax: + print ifelse(a < b, :A, :B) + + # parts A and B may require extensive processing, as in: + print ifelse(a < b, :ext_proc1(A), :ext_proc2(B)) + + 2) Locking: + + def with(alock, acallable): + alock.acquire() + try: + acallable() + finally: + alock.release() + + with(mylock, :x(y(), 23, z(), 'foo')) + +Implementation + + Implementation requires some tweaking of the Grammar/Grammar file + in the Python sources, and some adjustment of Modules/parsermodule.c + to make syntactic and pragmatic changes. + + (Some grammar/parser guru is needed to make a full implementation.) + + Here are the changes needed to Grammar to allow implicit lambda: + + varargslist: (fpdef ['=' imptest] ',')* ('*' NAME [',' '**' + NAME] | '**' NAME) | fpdef ['=' imptest] (',' fpdef ['=' + imptest])* [','] + + imptest: test | implambdef + + atom: '(' [imptestlist] ')' | '[' [listmaker] ']' | + '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ + + implambdef: ':' test + + imptestlist: imptest (',' imptest)* [','] + + argument: [test '='] imptest + + Three new non-terminals are needed: imptest for the place where implicit + lambda may occur, implambdef for the implicit lambda definition itself, + imptestlist for a place where imptest's may occur. + + This implementation is not complete. First, because some files in Parser + module need to be updated. Second, some additional places aren't + implemented, see Syntax section above. + +Discussion + + This feature is not a high-visibility one (the only novel part is + the absence of lambda). The feature is intended to make null-ary + lambdas more appealing syntactically, to provide lazy evaluation + of expressions in some simple cases. This proposal is not targeted + at more advanced cases (demanding arguments for the lambda). + + There is an alternative proposition for implicit lambda: implicit + lambda with unused arguments. In this case the function defined by + such lambda can accept any parameters, i.e. be equivalent to: + lambda *args: expr. This form would be more powerful. Grep in the + standard library revealed that such lambdas are indeed in use. + + One more extension can provide a way to have a list of parameters + passed to a function defined by implicit lambda. However, such + parameters need some special name to be accessed and are unlikely + to be included in the language. Possible local names for such + parameters are: _, __args__, __. For example: + + reduce(:_[0] + _[1], [1,2,3], 0) + reduce(:__[0] + __[1], [1,2,3], 0) + reduce(:__args__[0] + __args__[1], [1,2,3], 0) + + These forms do not look very nice, and in the PEP author's opinion + do not justify the removal of the lambda keyword in such cases. + +Credits + + The idea of dropping lambda was first coined by Paul Rubin at 08 + Feb 2003 16:39:30 -0800 in comp.lang.python while discussing the + thread "For review: PEP 308 - If-then-else expression". + +Copyright + + This document has been placed in the public domain. + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +sentence-end-double-space: t +fill-column: 70 +End: +