[Python-ideas] pep 312 - implicit lambdas idea

Gerald Britton gerald.britton at gmail.com
Sun Aug 9 13:03:43 CEST 2009


Your proposal certainly would lead to ambiguity in reading:
_ = myfunc
if _:_(_:_, ...)

The "if _:_" means:

   if '_' evaluates to boolean true, call it

The second _:_ uses your new lambda construct.  Could a compiler parse it?
Probably.  Can a human understand it? Maybe, with difficulty, but it would
surely lead to hard-to-find errors.

On Sun, Aug 9, 2009 at 3:29 AM, ilya <ilya.nikokoshev at gmail.com> wrote:

> 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
> >
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>



-- 
Gerald Britton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20090809/99b02a02/attachment.html>


More information about the Python-ideas mailing list