Query about proposed Multi-line Anonymous Function syntaxes

Hey all, my first time posting here. So, as I understand it, the main reason we don't have multi-line anonymous functions is because there has been no consensus about the syntax. I was just wondering if someone has a document detailing the various syntaxes that have been proposed in the the past. Adam

On Fri, Oct 10, 2014 at 8:06 AM, Adam Jorgensen <adam.jorgensen.za@gmail.com
wrote:
Well, it's worse -- it's hard to propose a syntax that actually works without huge changes to the way Python's parser treats indentation: inside parentheses, indentation is currently *not* significant.
I was just wondering if someone has a document detailing the various syntaxes that have been proposed in the the past.
No, but there have been many discussions. If you have a taste for mailing list archaeology it would be nice of you could dig up the various threads and summarize them for posterity, so at least we might make progress rather than going around in circles. As for myself, I have encountered a number of languages that do support multi-line anonymous functions (Java, JavaScript, CoffeeScript) and I have to say that for some reason they do not lead to very readable code. Especially in the latter two, the prevalent use for anonymous functions is for asynchronous I/O callbacks. I find Python 3.4's "yield from" as used by the asyncio library leads to much more readable code, without he need for callback functions at all. -- --Guido van Rossum (python.org/~guido)

On 10/10/2014 11:42 AM, Guido van Rossum wrote:
As for myself, I have encountered a number of languages that do support multi-line anonymous functions (Java, JavaScript, CoffeeScript) and I have to say that for some reason they do not lead to very readable code.
My take on the less-readable-code angle is that one of the main reasons for writing procedures is for abstraction: def some_func(spammer, target): """ fraggle the target with spammer """ You can look at that signature and have a rough idea of whats happening. On the other hand, anonymous blocks have the serious drawback of blowing your abstraction to bits: def some_func( multi_lambda: { /* many lines to define spammer /* } multi_lambda: { /* many lines to retrieve the target /* } ): { /* many lines to implement some_func /* } What a readability nightmare. -- ~Ethan~

On Fri, Oct 10, 2014, at 14:42, Guido van Rossum wrote:
What about forgetting about indentation entirely, and just using semicolons. You could use an extra semicolon to "break out" of the scope created by e.g. an if statement. lambda a: (if a: b; c;; else d; e;) equivalent to def f(a): if a: b return c else: d return e Basically, is the real reason people ask for multi-line lambdas because they want multiple lines, or just because they want multiple statements? And conversely, if you don't like the implications of allowing an unlimited number of statements of any kind on one line / within an expression, do you really want to give them multi-line lambdas, even if the syntax issue magically resolved itself?

On 11 Oct 2014 04:44, "Guido van Rossum" <guido@python.org> wrote:
On Fri, Oct 10, 2014 at 8:06 AM, Adam Jorgensen <
adam.jorgensen.za@gmail.com> wrote: parentheses, indentation is currently *not* significant.
I was just wondering if someone has a document detailing the various
syntaxes that have been proposed in the the past.
No, but there have been many discussions. If you have a taste for mailing
list archaeology it would be nice of you could dig up the various threads and summarize them for posterity, so at least we might make progress rather than going around in circles. There's also my 3 different documented suggestions aimed at this problem space: PEP 403 (overriding the name binding step for function and class definitions): http://www.python.org/dev/peps/pep-0403/ PEP 3150 (forward references to a trailing statement local namespace): http://www.python.org/dev/peps/pep-3150/ Suite expressions: http://python-notes.curiousefficiency.org/en/latest/pep_ideas/suite_expr.htm... The main stumbling block for all of them isn't getting agreement on syntax as such, but rather finding compelling examples that can't already be written more clearly by refactoring them to remove the need for a multi-line inline function. I don't have such examples myself, which is why both PEPs are deferred, and the last idea was never even submitted in the first place. Without such compelling examples, it's hard to judge the value of the syntax proposals themselves, as it's difficult to counter the "well, don't write it like that" argument. I asked various folks at SciPy earlier this year to look into coming up with such examples (as that was one of the best aspects of the matrix multiplication PEP), but haven't heard anything back as yet. Regards, Nick.

On Oct 10, 2014, at 11:42, Guido van Rossum <guido@python.org> wrote:
As a somewhat-related data point, compare the indentation rules in the standard Apple style for Objective C (as strongly encouraged by Xcode) before and after the addition of blocks (which are close enough to multi-line lambdas for this purpose). I don't know a single person who sat down at Xcode 3, or emacs ObjC-mode, or any of a half-dozen other assistive IDEs that all applied the same rules, and didn't pick up those rules within a few minutes of coding. But since blocks, there are full-time ObjC developers who are now on their third generation of Xcode versions and still fighting with it trying to start their code at column 70, and the rules in all those different IDEs are no longer consistent. Throwing suites into the middle of expressions inherently makes indentation more complicated. That's not to say that someone from the Python community couldn't solve this problem that Apple, Eclipse, JetBrains, etc. have failed at, just that the presumption going in shouldn't be that it's a trivial issue that's being used to unfairly dismiss a good idea.
As for myself, I have encountered a number of languages that do support multi-line anonymous functions (Java, JavaScript, CoffeeScript) and I have to say that for some reason they do not lead to very readable code. Especially in the latter two, the prevalent use for anonymous functions is for asynchronous I/O callbacks. I find Python 3.4's "yield from" as used by the asyncio library leads to much more readable code, without he need for callback functions at all.
A lot of code in these languages uses different techniques to flatten out the "callback hell". The most prevalent is probably deferred/promise objects. Although these are borrowed from Twisted from the Python world, the way they interact with JS-like syntax arguably makes them more useful there: Every callback is defined as the argument to a method on a promise, which means they start in a consistent place, toward the left edge of the screen, etc., and they rarely nest, which avoids most of the problems with inline function definitions while still allowing the benefits (not having to define the functions out of order, or give them meaningless names). Of course you could easily come up with a syntax based on one of Nick's two PEPs that's even nicer. And the fact that Python has an even better solution already (asyncio-style) makes it less interesting. Also, JS definitely encourages novices to write unreadable horrible code, even if it allows experienced developers to write it more cleanly, and I don't think that's a balance Python wants.

On 11 October 2014 09:26, Andrew Barnert <abarnert@yahoo.com.dmarc.invalid> wrote:
Note that it's also *not* a coincidence that some of my own suggestions are closer to Ruby's blocks than they are to multi-line lambdas. The exact way blocks work in Ruby is heavily reliant on the "accept a block as the last parameter to your function" convention, which makes them hard to adapt to an existing ecosystem like Python's, but they're still an elegant design pattern worth studying. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 10 October 2014 20:42, Guido van Rossum <guido@python.org> wrote:
Aaaaaah, this was exactly the area I figured would be an issue when I thought about the problem for more than 10 seconds :-)
I agree that anonymous functions do have the potential to produce illegible code, although I think this might be more a product of those languages general ability to enable said illegibility :-) In the context of python the only strong use-case I personally have for anonymous functions is a (extant) scenario where I'm writing nested decorators that don't use the decorator package to preserve signatures (There are some instances where signature preservation is actually undesirable :-). In this scenario the nested defs *might* be cleaner written in using anonymous functions, although there's no guarantee and it's not exactly a common scenario anyway... Maybe if I have some time I'll do the archaeology and cobble together a summary of the various proposals...
-- --Guido van Rossum (python.org/~guido)

On Tue, Oct 14, 2014 at 4:30 PM, Adam Jorgensen <adam.jorgensen.za@gmail.com> wrote:
Maybe if I have some time I'll do the archaeology and cobble together a summary of the various proposals...
Possibly the best format for such a summary would be a PEP, which can then be rejected. Then anyone else who wants to suggest multi-line lambdas can go to the PEP and try to come up with answers to all the objections. ChrisA

On Fri, Oct 10, 2014 at 8:06 AM, Adam Jorgensen <adam.jorgensen.za@gmail.com
wrote:
Well, it's worse -- it's hard to propose a syntax that actually works without huge changes to the way Python's parser treats indentation: inside parentheses, indentation is currently *not* significant.
I was just wondering if someone has a document detailing the various syntaxes that have been proposed in the the past.
No, but there have been many discussions. If you have a taste for mailing list archaeology it would be nice of you could dig up the various threads and summarize them for posterity, so at least we might make progress rather than going around in circles. As for myself, I have encountered a number of languages that do support multi-line anonymous functions (Java, JavaScript, CoffeeScript) and I have to say that for some reason they do not lead to very readable code. Especially in the latter two, the prevalent use for anonymous functions is for asynchronous I/O callbacks. I find Python 3.4's "yield from" as used by the asyncio library leads to much more readable code, without he need for callback functions at all. -- --Guido van Rossum (python.org/~guido)

On 10/10/2014 11:42 AM, Guido van Rossum wrote:
As for myself, I have encountered a number of languages that do support multi-line anonymous functions (Java, JavaScript, CoffeeScript) and I have to say that for some reason they do not lead to very readable code.
My take on the less-readable-code angle is that one of the main reasons for writing procedures is for abstraction: def some_func(spammer, target): """ fraggle the target with spammer """ You can look at that signature and have a rough idea of whats happening. On the other hand, anonymous blocks have the serious drawback of blowing your abstraction to bits: def some_func( multi_lambda: { /* many lines to define spammer /* } multi_lambda: { /* many lines to retrieve the target /* } ): { /* many lines to implement some_func /* } What a readability nightmare. -- ~Ethan~

On Fri, Oct 10, 2014, at 14:42, Guido van Rossum wrote:
What about forgetting about indentation entirely, and just using semicolons. You could use an extra semicolon to "break out" of the scope created by e.g. an if statement. lambda a: (if a: b; c;; else d; e;) equivalent to def f(a): if a: b return c else: d return e Basically, is the real reason people ask for multi-line lambdas because they want multiple lines, or just because they want multiple statements? And conversely, if you don't like the implications of allowing an unlimited number of statements of any kind on one line / within an expression, do you really want to give them multi-line lambdas, even if the syntax issue magically resolved itself?

On 11 Oct 2014 04:44, "Guido van Rossum" <guido@python.org> wrote:
On Fri, Oct 10, 2014 at 8:06 AM, Adam Jorgensen <
adam.jorgensen.za@gmail.com> wrote: parentheses, indentation is currently *not* significant.
I was just wondering if someone has a document detailing the various
syntaxes that have been proposed in the the past.
No, but there have been many discussions. If you have a taste for mailing
list archaeology it would be nice of you could dig up the various threads and summarize them for posterity, so at least we might make progress rather than going around in circles. There's also my 3 different documented suggestions aimed at this problem space: PEP 403 (overriding the name binding step for function and class definitions): http://www.python.org/dev/peps/pep-0403/ PEP 3150 (forward references to a trailing statement local namespace): http://www.python.org/dev/peps/pep-3150/ Suite expressions: http://python-notes.curiousefficiency.org/en/latest/pep_ideas/suite_expr.htm... The main stumbling block for all of them isn't getting agreement on syntax as such, but rather finding compelling examples that can't already be written more clearly by refactoring them to remove the need for a multi-line inline function. I don't have such examples myself, which is why both PEPs are deferred, and the last idea was never even submitted in the first place. Without such compelling examples, it's hard to judge the value of the syntax proposals themselves, as it's difficult to counter the "well, don't write it like that" argument. I asked various folks at SciPy earlier this year to look into coming up with such examples (as that was one of the best aspects of the matrix multiplication PEP), but haven't heard anything back as yet. Regards, Nick.

On Oct 10, 2014, at 11:42, Guido van Rossum <guido@python.org> wrote:
As a somewhat-related data point, compare the indentation rules in the standard Apple style for Objective C (as strongly encouraged by Xcode) before and after the addition of blocks (which are close enough to multi-line lambdas for this purpose). I don't know a single person who sat down at Xcode 3, or emacs ObjC-mode, or any of a half-dozen other assistive IDEs that all applied the same rules, and didn't pick up those rules within a few minutes of coding. But since blocks, there are full-time ObjC developers who are now on their third generation of Xcode versions and still fighting with it trying to start their code at column 70, and the rules in all those different IDEs are no longer consistent. Throwing suites into the middle of expressions inherently makes indentation more complicated. That's not to say that someone from the Python community couldn't solve this problem that Apple, Eclipse, JetBrains, etc. have failed at, just that the presumption going in shouldn't be that it's a trivial issue that's being used to unfairly dismiss a good idea.
As for myself, I have encountered a number of languages that do support multi-line anonymous functions (Java, JavaScript, CoffeeScript) and I have to say that for some reason they do not lead to very readable code. Especially in the latter two, the prevalent use for anonymous functions is for asynchronous I/O callbacks. I find Python 3.4's "yield from" as used by the asyncio library leads to much more readable code, without he need for callback functions at all.
A lot of code in these languages uses different techniques to flatten out the "callback hell". The most prevalent is probably deferred/promise objects. Although these are borrowed from Twisted from the Python world, the way they interact with JS-like syntax arguably makes them more useful there: Every callback is defined as the argument to a method on a promise, which means they start in a consistent place, toward the left edge of the screen, etc., and they rarely nest, which avoids most of the problems with inline function definitions while still allowing the benefits (not having to define the functions out of order, or give them meaningless names). Of course you could easily come up with a syntax based on one of Nick's two PEPs that's even nicer. And the fact that Python has an even better solution already (asyncio-style) makes it less interesting. Also, JS definitely encourages novices to write unreadable horrible code, even if it allows experienced developers to write it more cleanly, and I don't think that's a balance Python wants.

On 11 October 2014 09:26, Andrew Barnert <abarnert@yahoo.com.dmarc.invalid> wrote:
Note that it's also *not* a coincidence that some of my own suggestions are closer to Ruby's blocks than they are to multi-line lambdas. The exact way blocks work in Ruby is heavily reliant on the "accept a block as the last parameter to your function" convention, which makes them hard to adapt to an existing ecosystem like Python's, but they're still an elegant design pattern worth studying. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 10 October 2014 20:42, Guido van Rossum <guido@python.org> wrote:
Aaaaaah, this was exactly the area I figured would be an issue when I thought about the problem for more than 10 seconds :-)
I agree that anonymous functions do have the potential to produce illegible code, although I think this might be more a product of those languages general ability to enable said illegibility :-) In the context of python the only strong use-case I personally have for anonymous functions is a (extant) scenario where I'm writing nested decorators that don't use the decorator package to preserve signatures (There are some instances where signature preservation is actually undesirable :-). In this scenario the nested defs *might* be cleaner written in using anonymous functions, although there's no guarantee and it's not exactly a common scenario anyway... Maybe if I have some time I'll do the archaeology and cobble together a summary of the various proposals...
-- --Guido van Rossum (python.org/~guido)

On Tue, Oct 14, 2014 at 4:30 PM, Adam Jorgensen <adam.jorgensen.za@gmail.com> wrote:
Maybe if I have some time I'll do the archaeology and cobble together a summary of the various proposals...
Possibly the best format for such a summary would be a PEP, which can then be rejected. Then anyone else who wants to suggest multi-line lambdas can go to the PEP and try to come up with answers to all the objections. ChrisA
participants (8)
-
Adam Jorgensen
-
Andrew Barnert
-
Chris Angelico
-
Ethan Furman
-
Guido van Rossum
-
João Santos
-
Nick Coghlan
-
random832@fastmail.us