On Sun, Oct 21, 2018 at 6:39 PM Chris Angelico
Sure, but can you give examples where you can't use lambda, but still want it to have no name?
I can try kinda answering this: It's less with everyday built-ins and the standard library (though see first example below), and more with libraries and frameworks that want callbacks (or callables in general) passed in. Sometimes I need that callable to be something very simple, but it technically can't be a lambda because it has a statement in it. Defining it as a function forces me to give it not only a name, but a place too. Defining it just before the point of use is a natural location in one sense, but it makes the visual flow of the code worse, especially if I need to make several such steps (with different almost-lambdas) in a row.
From the standard library, I can actually think of Thread:
t1 = Thread(target=(lambda: counter += 1)) t2 = Thread(target=(lambda: sum += current_quux())) Because they include statements, it needs to be: def inc_counter(): counter += 1 t1 = Thread(target=inc_counter) def update_sum(): sum += current_quux() t2 = Thread(target=update_sum)
From one popular library:
ws = websocket.WebSocketApp( url, on_open = (lambda ws: ws.send('subscribe'); conn_counter += 1), on_message = (lambda ws, msg: print(msg); msg_counter += 1)) Because they include statements, I again need to create those functions separately. Naming isn't so much a problem here, but it would turn kludgey if I needed to make several such calls in the same scope. In any case, that's a common little frustration I often put up with. I think most other languages around Python's power level don't make that a problem. To expand that argument a bit, lambdas have access to names in their immediate context that can be more of a pain with less-local functions. For a toy example: [(lambda a: print(x + a)) for x in l] When print was a statement, defining this lambda as a named function would have had to use more arguments. The richer the context, the more noise it would have added. BTW, don't treat the above `(lambda: stmt)` syntax as a _proposal_ per se, BUT: No matter what we allow inside a lambda, from the outside it's an expression. How do we make a Python expression span multiple lines? In simplified terms, we put it in parentheses. How do we separate an expression whose boundaries would be ambiguous in a given context (e.g. a tuple literal inside a parameter list)? We put it inside a pair of parentheses. Hmm. I mean, these already work: (lambda: 2 + 3) lambda: 2 + ( 3) They're multi-LINE lambdas, just not multi-statement (or even uni-statement). If Python _was_ to somehow allow statements inside lambdas at all at some point in the future (which I don't expect), I don't see that that would then need any additional special syntax for multi-line-ness or for separating them from the surrounding context.