# Simple multi-line lambda syntax

**URL:** <https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499>\
**Category:** Ideas\
**Tags:** typing\
**Created:** [June 7, 2023, 5:53pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499 "2023-06-07T17:53:14Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tersoo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/tersoo/32/12797_2.png) [@tersoo](https://discuss.python.org/u/tersoo)\
**Post date:** [June 7, 2023, 5:53pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/1 "2023-06-07T17:53:14Z")

</div>

Supports type hints and does not break python semantics afaik

```py
app.watch('message', lambda (message: str, origin: str) -> bool: (
    # multi-line code here
))

```

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [June 7, 2023, 6:11pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/2 "2023-06-07T18:11:25Z")

</div>

Isn’t this already possible?

```auto
>>> 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.

---

<div class="post-metadata">

**Author:** ![tersoo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/tersoo/32/12797_2.png) [@tersoo](https://discuss.python.org/u/tersoo)\
**Post date:** [June 7, 2023, 7:20pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/3 "2023-06-07T19:20:49Z")

</div>

Already possible as long as you have no assignments within parentheses. i.e. `print(msg)` can not be replaced with `msg = ...`.

---

<div class="post-metadata">

**Author:** ![da-woods](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/da-woods/32/7507_2.png) [@da-woods](https://discuss.python.org/u/da-woods)\
**Post date:** [June 7, 2023, 9:17pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/4 "2023-06-07T21:17:35Z")

</div>

`from __future__ import braces`

---

<div class="post-metadata">

**Author:** ![tjreedy](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/tjreedy/32/137_2.png) [@tjreedy](https://discuss.python.org/u/tjreedy)\
**Post date:** [June 7, 2023, 9:49pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/5 "2023-06-07T21:49:13Z")

</div>

Even assignment expressions work with lambda expressions.

```auto
>>> (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.

---

<div class="post-metadata">

**Author:** ![effigies](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/effigies/32/35835_2.png) [@effigies](https://discuss.python.org/u/effigies)\
**Post date:** [June 8, 2023, 2:15pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/6 "2023-06-08T14:15:46Z")

</div>

With assignment expressions and a function to select a return expression, you can get most of the way there.

```python
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.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [June 8, 2023, 3:21pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/7 "2023-06-08T15:21:19Z")

</div>

That’s true, although in this situation, I would _much_ rather go the other direction, and convert the call into a decorator:

```auto
def watch(what):
    def inner(cb):
        app.watch(what, cb)
        return cb
    return inner

@watch("message")
def incoming_message(message, origin):
    ...

```

---

<div class="post-metadata">

**Author:** ![effigies](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/effigies/32/35835_2.png) [@effigies](https://discuss.python.org/u/effigies)\
**Post date:** [June 8, 2023, 6:36pm UTC](https://discuss.python.org/t/simple-multi-line-lambda-syntax/27499/8 "2023-06-08T18:36:41Z")

</div>

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:

```python
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:
    ...

```
