On Fri, Nov 8, 2019 at 11:22 PM Antoon Pardon <antoon.par...@vub.be> wrote: > > On 8/11/19 13:00, Chris Angelico wrote: > > On Fri, Nov 8, 2019 at 10:57 PM Antoon Pardon <antoon.par...@vub.be> wrote: > >> On 7/11/19 18:10, Stephen Waldron wrote: > >>> What I'm aiming for is the ability to, within a function call, pass a > >>> suite that would be there automatically defined by the > >>> compiler/interpreter. Another comment did mention lambda functions, which > >>> does to some degree provide that capability, but is restricted to well, > >>> lambda functions (only expressions, not statements). > >> I don't think those restrictions are that limiting. Certainly not since > >> python3.8 and python acquired an assigment operator. And you should also > >> note that a list is an expression. So we could do something like the > >> following. > >> > > If you're implying that you can rewrite any function using lambda and > > a list of expressions, then no, the ":=" operator won't help you: > > > >>>> (lambda: x := 1) > > File "<stdin>", line 1 > > SyntaxError: cannot use named assignment with lambda > > Well I haven't had the time to install python3.8 myself but this is what > I read in the PEP > > * Unparenthesized assignment expressions are prohibited in lambda > functions. Example: > (lambda: x := 1) # INVALID > lambda: (x := 1) # Valid, but unlikely to be useful > (x := lambda: 1) # Valid > lambda line: (m := re.match(pattern, line)) and m.group(1) # Valid > > This allows lambda to always bind less tightly than :=; having a > name binding at the top level inside a lambda function is unlikely > to be of value, as there is no way to make use of it. In cases where > the name will be used more than once, the expression is likely to > need parenthesizing anyway, so this prohibition will rarely affect code. > > So it seems you just forgot to use the parenthesis. >
True, I could make it syntactically valid with parens. But as the paragraph shows, it's still not possible to use it outside that lambda function (there's no way to declare it nonlocal), and you can't assign to anything other than a simple name (no "x[1] := 1"), so you still can't use this as a true replacement for 'def' functions. I kinda shorthanded with the example but it's still a very tight limitation. Going back to looking at the way JavaScript does things, though: One of the main places that large functions are commonly used as arguments is asynchronous code. There are better ways to do that (async/await in both languages, threads and processes in Python), so that's not necessary. For event driven code, I would much prefer to use 'def' functions with decorators, rather than function arguments - compare a bit of Python/Flask code with a similar bit of JS/Express: @app.route("/foo/<id>") def foo(id): return ... app.get("/foo/:id", (req, res) => { res.send(...) }); Pretty similar, but one very important distinction is that the Flask style extends easily to multi-routing, simply by decorating the function more than once. For event-driven code (this is for an HTTP server, and the same applies to a GUI), this is a way cleaner way to do things. I'd rather look into ways to make decorators do what you need (even if that involves an enhancement to decorator syntax) than try to create multi-line lambdas. ChrisA -- https://mail.python.org/mailman/listinfo/python-list