Sorry for bumping this.
I primarily use python, and love it the way it is, and have learnt to live with it’s design decisions. Nonetheless, I have missed this feature in a few occasions. One of which is bdd
style testing akin to rspec
/ cucumber.js
. Again, this is not a deal breaker, as I stated I have learnt to live with this (e.g. I use pytest-bdd
, which is nowhere as nice, and many things aren’t well defined, but can be made to work).
If there were a way to do multiline lambdas in Python, I would be on it in Planck time. Now, as I understand, the main blocker seems to be the syntax. Once one gets past this hurdle, only then the idea would be worthy of serious consideration.
I recently had an #idea
for one (ok, maybe two) such syntax. I believe it is:
- pythonic (IMHO)
- familiar to python users
- clearly (too clearly) delineates the anonymous block
- would work well in IDLE
NOTE: This is purely a demonstration of syntax. So I haven’t tried to demonstrate any usefulness of such pattern. If this syntax is palatable, then first, discussions could be had about finer points of the syntax, associated constraints, and finally, on the merits of multiline lambdas on whole.
Option 1:
- IMO most familiar,
- probable nightmare for parser? (but doctest, idle are used to this)
- two many new tokens, changes to the grammar, for a feature that may see sparse use?
- way too much ceremony for marking a block? hopefully IDEs and IDLEs can autofill
- I like this one the most
def insanity() -> Callable[[int], Callable[[int, int], Foo]]:
# doing a lot of stuff here
return (
>>> def (a: int) -> Callable[[int, int], Foo]:
... # doing a lot of stuff here
... return (
... >>> def (x: int, y: int) -> Foo:
... ... return Foo(
... ... x,
... ... y,
... ... >>> def (z):
... ... ... return x + y + z
... ... ...,
... ... x + y,
... ... )
... ...
... )
...
)
Option 2:
- less ceremony
- probably less work for the parser (I don’t know)
def insanity() -> Callable[[int], Callable[[int, int], Foo]]:
# doing a lot of stuff here
return (
| def (a: int) -> Callable[[int, int], Foo]:
| # doing a lot of stuff here
| return (
| | def (x: int, y: int):
| | return Foo(
| | x,
| | y,
| | | def (z):
| | | z = x ** y
| | | return x + y + z
| | |,
| | x + y,
| | )
| |
| )
|
)
I have slight preference for def
, but I have no problem with lambda
if it is deemed more suitable.
PS: Probably something about the above syntax (or the entire thing) is absolutely horrible, and make no sense in terms of language design, if it is then I offer my sincerest apologies for wasting your time. Even though I have written some toy parsers, I am not a language design expert, I am sure more experienced people than me (as you all are) would be better judges.