Supports type hints and does not break python semantics afaik
app.watch('message', lambda (message: str, origin: str) -> bool: (
# multi-line code here
))
Supports type hints and does not break python semantics afaik
app.watch('message', lambda (message: str, origin: str) -> bool: (
# multi-line code here
))
Isn’t this already possible?
>>> print(lambda msg: (
... print(msg),
... print(msg),
... ))
<function <lambda> at 0x7f4e5da1fd80>
>>>
Multiple lines have never been disallowed. But lambda functions have always been defined as a single expression, as opposed to def functions which are a suite of statements. Your proposal would still have the code enclosed in parentheses and therefore almost certainly an expression; if it isn’t, that would be a far greater backward compatibility break than you were expecting.
Already possible as long as you have no assignments within parentheses. i.e. print(msg)
can not be replaced with msg = ...
.
from __future__ import braces
Even assignment expressions work with lambda expressions.
>>> (lambda x: (a:=x*2) + a)(3)
12
Name ‘a’ is not defined outside the expression, just as it would not be for the exquivalent def statement and call.
With assignment expressions and a function to select a return expression, you can get most of the way there.
returning = lambda *exprs: itemgetter(-1)(exprs)
noreturn = lambda *exprs: None
lambda arg1, arg2: noreturn(
expr1,
expr2,
...
)
app.watch('message', lambda message, origin: returning(
# expression list
))
I do think the type annotations would be nice for lambdas. I think I’ve seen discussions where it was generally rejected, but I can’t readily find them now.
That’s true, although in this situation, I would much rather go the other direction, and convert the call into a decorator:
def watch(what):
def inner(cb):
app.watch(what, cb)
return cb
return inner
@watch("message")
def incoming_message(message, origin):
...
Huh, I don’t think I’ve seen that pattern of decorating callbacks before, but makes sense. I think I would generalize it to not include any interesting detail inside the decorator, so everything is right at function definition:
from functools import partial
def callback(caller, *args, **kwargs):
init = partial(caller, *args, **kwargs)
def inner(cb):
init(cb)
return cb
return inner
...
@callback(app.watch, "message")
def incoming_message(message: str, origin: str) -> bool:
...