[Python-ideas] Multi Statement Lambdas

Vladimir Filipović hemflit at gmail.com
Tue Oct 23 05:03:21 EDT 2018


Chris, I'm happy to work with you to hammer out comparisons of various
solutions.

But I can't take on the role of an advocate for "multi-statement lambdas".
I don't even understand what precisely that covers, since we don't have
uni-statement lambdas.
_If that role would be needed for this discussion, the rest of what I'm
about to write may be a waste of your time!_

I got involved in this thread because examples of something were asked for,
and I had a couple. I could defend a claim like "some _limited set_ of
statements inside lambdas would be useful and pythonic", if that's a useful
conversation to have.

(My view BTW is that _indented compound statements_ in lambdas would be
_irreducibly_ unpythonic, and the only way that can change is if the
concept of pythonicity happens to drift over time.)

------

> Next step: Offer a variety of alternate
> syntaxes that *do* currently work, and then the proposed
> multi-statement lambda, and show how the current syntaxes are all
> ugly.

Good, but we may have a disconnect about which "ugliness"/problem is being
solved.

The central point of Python's lambdas, for me, is that when one needs to
refer to a _very simple_, _once-off_ function, lambdas _make the code
better._
The ways they make it better go beyond saving vertical space and can be
subtle: they improve the locality of code by allowing the function's
definition to be exactly in the place where it's used; a lot like the
difference between (in pseudocode) `output("Hello, world")` and having to
say `String hw = new String("Hello, world"); output(hw)`.


So, what does the existing lambda feature offer in those situations?

1. Virtually no pomp and ceremony (one keyword, sometimes needs
parentheses, no compulsory newlines).

2. Relieves me from having to decide on the place for the definition (right
before use? at the beginning of the using function/scope? right before the
using function/scope?). This could be resolved by just having a convention,
but I note there isn't an existing convention ("Schelling point") for the
just-define-a-named-function approach.

3. That code-locality thing. It relieves me as reader from having to
mentally connect its definition to its usage, and from having to deduce
that it's not also used elsewhere.

4. Relieves me from having to come up with a one-use name. No, `foo` isn't
as good.

5. (I shouldn't have to include this but) Expressions don't lose clarity by
being moved into a lambda. Past the keyword itself, the contents of the
lambda look exactly like (= as simple as) what I would write in non-lambda
Python code. I don't need to contort them into special lambda-specific
constructs.

None of those things are _universally_ desirable! But the existing lambda
lets me _choose_ that in some particular case (very simple, once-off
function) they do make the code better, so I can get them.


Except that sometimes I need a _very simple_, _once-off_ function that
would do something that's a statement. It seems like a very similar
situation, the concept doesn't seem antithetical to the philosophy of
Python's existing lambdas, so it's a bit frustrating that I can't choose to
use the same feature and reap those same benefits.

Other times, I want the lambda to do a couple of things in sequence. No ifs
or try-finallys, just one thing with its side-effects, followed by the
other. This is already doable as evaluation of a tuple (if the things are
expressions), and that's not _too_ ugly, but it would become more direct
(as in quality #5 above) if it was expressible as a pair of
expression-statements.

------

Okay now, what does the decorator solution do in that WebSocket situation
that just defining named functions doesn't already?

I suppose it helps somewhat with property #2 above (finding a place for the
definition).
Outside of that list, it lets us shorten the constructor call.

Am I missing something? Or am I moving the goalposts - were you explicitly
trying to solve something else?

------

Let me try to anticipate one more existing solution (the best I came up
with):

Where the statement is about updating counters or similar state variables,
we can make them items in a dict (or collections.Counter) instead, and
update them in a lambda via dict.update().

It's not terrible, but it means all other references to the state variable
must change in a way that makes them less clear. ("Why are they using this
dict at all? Ohh, because lambda.")

And having to replace `c += 1` with `d.update(c = d['c'] + 1)` or
`counter.update(c=1)` is still ugly.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20181023/0c556018/attachment.html>


More information about the Python-ideas mailing list