[Python-ideas] pep 312 - implicit lambdas idea
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
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
>> 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:
> 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
> while _:
> _ = 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)
> 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(
> 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
> magic=12345, # this needs no documentation
> _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
More information about the Python-ideas