[Python-ideas] pep 312 - implicit lambdas idea

ilya ilya.nikokoshev at gmail.com
Sun Aug 9 09:29:37 CEST 2009


Thank you and everyone else for insightful posts detailing why my
examples don't make a good argument for the syntax.

Even though my original suggestion, similarly pep 312, wouldn't break
any existing programs and would not lead to ambiguity in 'if _:', I
rescind it.

However, another reason for implicit lambdas is lazy evaluation. For
example, in another thread people discuss "... except ... if/else"
conditional statement --- one reason being control expressions
evaluate lazily. A function call passing callables currently looks
ugly and unreadable:

    lazy_cond(expr, lambda: expensive(5), lambda: factorial(10**5))

and here 6 keystrokes of 'lambda' word *do* matter.

Therefore I hope my unsuccessful proposal will encourage people to
find something that works.


On Sat, Aug 8, 2009 at 4:21 AM, Steven D'Aprano<steve at pearwood.info> wrote:
> On Fri, 7 Aug 2009 10:46:40 pm ilya wrote:
>> I was thinking about a good syntax for implicit lambdas for a while
>> and today I had this idea: make ``_:`` a shortcut for ``lambda
>> _=None:``
>
> [...]
>
>> The rationale is that you only want to get rid of lambda keyword to
>> create a *very* simple function, the one that will be called either
>> without parameters or with only one parameter. For everything more
>> complicated, you really should go and write the explicit function
>> signature using lambda.
>
> Why would you want to get rid of the lambda keyword? What's the benefit?
>
> Is this about saving twelve keystrokes?
>
> lambda _=None:
>  versus
> _:
>
> Just how often do you want, or need, to write such a lambda? It seems to
> me that not only is it a special case you want to break the rules for,
> which goes against the Zen, but it's an incredibly rare special case.
>
> _ as an identifier already has three conventional meanings:
>
> (1) In the interactive interpreter, _ is the value of the last
> expression typed.
>
> (2) It is commonly used to mean "I don't care about this value", e.g.
>
> t = ("Fred Smith", "123 Fourth Street", "New York", "dog")
> name, _, _, pet = t
>
> (3) It is also often used in internationalization.
>
> You want to give it the extra meaning "a default parameter name for
> lambda when I can't be bothered typing even a single letter name".
>
> Because _ is already a valid identifier, this will break code that does
> this:
>
> while _:
>    process()
>    _ = function()
>
> if _:
>    print "something"
>
>
> Not the best choice of names, but somebody, somewhere, is doing that,
> and your suggestion will break their code.
>
>
> Looking at the three examples you gave:
>
> map( _: _ + 5, some_list)
> register_callback( _: True)
> def apply_transform(..., transform = _:_, ... ):
>
> In the first case, I wouldn't use the short-cut form even if it were
> available. I'd write a lambda that used a more meaningful name. In this
> case, I'm expecting an int, so I would use n, or a float, so I'd use x.
> I'd also avoid setting the pointless default:
>
> map(lambda x: x+5, some_list)
>  vs
> map(_: _+5, some_list)
>
> Since your suggestion doesn't do precisely what I want, the only reason
> I would have for using your construct is to save seven keystrokes.
> Encouraging laziness on the behalf of the programmer is not a good
> reason for special-casing rare cases.
>
> Second case: register_callback( _: True)
>
> I assume you're implying that the callback function must take a single
> argument. In this example, using _ as the parameter name to the lambda
> makes sense, because it is a "don't care" argument. But if the callback
> function is documented as always being given a single argument, I would
> want to know if it was being called without any arguments, so the
> default value of None is inappropriate and I would avoid using it.
>
> Third case: def apply_transform(..., transform = _:_, ... ):
>
> I don't think I'd write a function called apply_transform() which made
> the transformation function optional, let alone buried deep in the
> middle of a whole lot of extra parameters. (I presume that's what
> the "..."s are meant to imply.) But putting that aside, I see your
> intention: a default do-nothing function which appears in a very long
> parameter list. The problem is that instead of trying to shrink the
> default value so you can fit all the parameters on a single line, you
> should make such a complicated function signature more readable by
> spreading it out:
>
> def apply_transform(
>    obj,
>    start, end,      # start (inc) and end (exc) positions to apply
>    another_arg,     # does something very important I'm sure
>    x=0, y=1, z=2,   # more very important arguments
>    transform=(      # default null transformation
>              lambda obj=None: obj),
>    frotz=False,     # if true, frotz the hymangirator with spangule
>    hymangirator=None,
>    spangule=None,
>    magic=12345,     # this needs no documentation
>    namespace={},
>    flibbertigibbet=None,
>    _private_magic=[]  # the caller shouldn't supply this
>    ):
>
> (Even better is to avoid such complicated function signatures, but
> sometimes that's not an option.)
>
> So again I'd be very unlikely to use your suggested construct except out
> of simple can't-be-bothered-to-type-a-dozen-letters laziness. Pandering
> to that sort of laziness is probably not a good thing.
>
> Fundamentally, this suggestion doesn't add expressability to the
> language, or power. Laziness on it's own is not a good reason for
> special casing rare cases. If it was a very common case, then *perhaps*
> you would have an argument for special casing needless verbiage:
> conciseness (up to a point) is a virtue in a language. That's partly
> why we have lambdas in the first place, so we can write this:
>
> reduce(lambda a,b: (a+b)/2.0, somelist)
>
> instead of this:
>
> def average(a, b):
>    return (a+b)/2.0
> reduce(average, somelist)
>
> But this isn't a common case, it's a rare case, and the case you're
> hoping to replace is pretty concise already.
>
>
>
> --
> Steven D'Aprano
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>



More information about the Python-ideas mailing list