
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