Chris Angelico writes:
 > On Wed, Jan 6, 2021 at 9:27 PM Steven D'Aprano <[email protected]> wrote:

 > > I'm glad that things like Perl one-liners, obfuscated C, and
 > > sewerage treatment works exist...
 > 
 > :)

+1

 > > Multi-statment anonymous functions are, in my opinion, overrated, and a
 > > (slight) code smell. If your lambda is so complex it requires more than
 > > a single expression, shouldn't it have documentation and tests?

That's a great exaggeration.  Less so now that we have the conditional
expression, comprehensions, and genexps, but still....

In Lisp, you can actually substitute a defun for a lambda because the
defun returns a callable (a symbol similar to a Python function
object).  "It's a bold strategy, Cotton."  Not sure it would pay off
in Python.  But see below.

 > There are some other use-cases, where something is syntactically an
 > anonymous function, but in practice, it's a part of some larger
 > construct. In Python, a lot of those use-cases are handled by some
 > form of function decorator or maybe abuse of class notation, but I
 > wouldn't rule out the possibility that there are cases where those are
 > suboptimal.
 > 
 > Consider UI building, for instance. You need to have event handler
 > functions, and you need to build your UI. There are a few
 > possibilities:
 > 
 > 1) Magic names within a class. If you have a thing called "btn_frob",
 > and a function called "btn_frob_clicked", then that function will
 > automatically be called when the button is clicked.
 > 2) Objects have function decorators as attributes, so
 > "@btn_frob.clicked" will define the function to be called when the
 > button is clicked.
 > 3) Name all your event handlers and place them out of line, allowing
 > you to use simple function parameters to associate them.
 > 4) Define a dict with attributes, and use lambda functions to handle
 > events eg {"clicked": lambda: ...}
 > 
 > Nothing's perfect, and nothing ever will be, but you can see how
 > option 4 would become more viable with multiline lambdas. The function
 > can definitely be anonymous,

*Any* function can be anonymous.  Just copy the lambda around as you
need it.  Inline for efficiency. ;-)  The question is the tradeoff
between availability of a name *in multiple contexts* and the
annoyance of choosing one.  In the case in point, you'd have to depend
on the UI builder class to associate the event name with the anonymous
handler for debugging, for example.

Suppose that lambda had this syntax:

    lambda PARAMETER-TUPLE [NAME]: DEFINITION

Then you could use a list: [lambda (context) clicked: ...].  Note
that this list doesn't need to pollute the namespace (and in that
sense would be anonymous).  The lambda would know its own name, and
the builder or the runtime would fish that out.  (I can see a number
of reasons why this "fishing" design would not be great, and the
system might duplicate the name in an attribute for straightforward
access.  But I suspect that's also true of the dict design.)

I am specifically suggesting that the presence of the NAME parameter
gives lambda's DEFINITION the syntax of def.

 > testing and documentation apply to the entire UI rather than to any
 > specific function (it's generally useless to try to unit-test a
 > single event handler function outside of its context),

This is inaccurate in both directions.  First, you generally don't
need the whole UI.  You need the context, which is a compact
representation of the history of the UI's behavior.  Second, the need
for context is present any time you don't have a pure function, which
in Python practice is most of the time.

 > and most importantly, defining it out of line separates relevant
 > and related concepts.

There may be better examples, but I think that UI is not a good one
here.  For all practical purposes, a UI element is a collection of
event handlers.  A series of defs with descriptive names is more than
sufficient to associate the related concepts.  Collect them in a list,
hand it to the UI, and then let the UI format them as it pleases.

 > an ugly multiline lambda won't be better than the alternatives,

The multiline lambda can't be worse than my suggestion above, which is
just a def that returns the function object without associating it
with any name in the enclosing namespace.  Are defs so ugly?

 > [If] anyone comes up with a really elegant syntax, I'd love to
 > discuss it and help with PEP authorship.

Before anyone asks, I'm not interested in authoring this PEP. ;-)

Steve

_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/M4M3PBRX3UZ72ALJ3HM6V4L2CRHDAHDW/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to