News for hackers. Stuff that matters.
Re:Toolz: A functional standard library for Python by heavyset_go on Thursday January 21, 2021 @02:47PM (#25863245)
Yeah, Python would really benefit from multi-line anonymous functions.

There was a limitation in Python where spacing and indentation gets ignored between parentheses, which makes it impossible to pass a multi-line lambda as an argument to a method or function. However, given the new parser, that limitation might be able to be mitigated.

Re:Toolz: A functional standard library for Python by mumblemumble on Thursday January 21, 2021 @06:04PM (#25865841)
I would argue that multi-line anonymous functions are unpythonic. Exhibit A is this line from PEP 20:

  Readability counts.

I'm currently about a month into learning a legacy codebase that was written in a functional language. If I could single out one thoroughly egregious practice that has made this code far, far more difficult to read and understand than it should have been, it's multi-line anonymous functions. In general, if a function is doing something complicated enough to need multiple lines of code, it's doing something complicated enough to merit an explicit name.
Re:Toolz: A functional standard library for Python by uryga on Thursday January 21, 2021 @07:39PM (#25866763)
> if a function is doing something complicated enough to need multiple lines of code, it's doing something complicated enough to merit an explicit name.

  def foo_and_bar(x):
    foo(x)
    bar(x)
whew! good thing i named that

IME this limitation just leads to throwaway names like

  process(x)
  go(x)
  do_foo(x) # in foo(x)
  cb/callback/fn
because a lot of things just don't have sensible names! just like how it'd suck to have to come up with a name for every loop body

(although there was some book advocating for "replace every loop body with a named function" so some people enjoy that i guess...)

Re:Toolz: A functional standard library for Python by mumblemumble on Thursday January 21, 2021 @08:25PM (#25867061)
I see you chopping the first two words off that quote. ;)

In this specific case, that single instance of a single pattern is such a throw-away that it doesn't deserve a name, but the pattern itself is easy enough to name. So I'd skip the single-purpose function and create a combinator.

  def do_each(*args):
    def helper(x):
      for fn in args:
        fn(x)
    return helper
and then, when I need to do both foo and bar, I don't even need a lambda.

  map(do_each(foo, bar), some_sequence)
That's a fairly specific case, though. Moving back to the general, I would say that a function that does more than one thing, but can't easily be named, is a code smell.

Of course, every general rule has its exceptions. But I'm not so keen on the idea of optimizing one's coding style for the exceptional cases. Going back to PEP 20, "Special cases aren't special enough to break the rules."

(I realize mapping a function that returns nothing is terrible, but I'm feeling too lazy to think of a better example.)

Re:Toolz: A functional standard library for Python by uryga on Friday January 22, 2021 @04:34AM (#25870013)
i like a nice combinator as much as the next person! but consider this: if python already had multiline lambdas, would you be arguing for using a narrow-purpose combinator instead of `lambda x: foo(x); bar(x)`?

[this kind of reminds me of Go's generics mess, where workarounds for lack of generics are "just how you write Go and that's the language's philosophy"... until generics land and suddenly they won't be]

Re:Toolz: A functional standard library for Python by mumblemumble on Friday January 22, 2021 @08:32AM (#25871486)
Probably. I think the former is more readable and, at the use site, more concise.

Regardless, I don't think the hypothetical is super useful, because its unstated major premise is, "But what if we, for the sake of argument, ignore all the other good reasons why Python doesn't have them?"

My favorite programming language is functional, and has significant whitespace and multiline anonymous functions. While it is my favorite, I do have to concede that the Python language maintainers' worries about the syntactic implications of multiline lambdas in a whitespace language are accurate.

(I could quote the zen of python some more here, too. Lines 5 and 6.)

Re:Toolz: A functional standard library for Python by heavyset_go on Friday January 22, 2021 @06:49PM (#25877868)
Assignment expressions were "unpythonic" based on PEP 20 until they weren't. Modern languages have multi-line anonymous functions, and developer expectations have changed in the 17 years since PEP 20 was published.
Re:Toolz: A functional standard library for Python by high_density on Sunday January 24, 2021 @01:21AM (#25889803)
the thing with python is that it's "indentation-based" -- it's difficult to see "where does this anonymous function return or end?"

maybe it's time to allow optional brackets for marking where a function starts and ends? eg. a { ... } (or anything else -- even {| ... |} will do)

Re:Toolz: A functional standard library for Python by tutfbhuf on Thursday January 21, 2021 @02:53PM (#25863333)
But you can define functions inside of functions (recursively).

  def function1():
      print ("hello outer")
      def function2():
          print ("hello inner")
      function2()

  function1()
Output:

  hello outer
  hello inner
Re:Toolz: A functional standard library for Python by throwaway894345 on Thursday January 21, 2021 @03:15PM (#25863626)
But you can’t do that (or try/except) in an expression such as a list comprehension or similar.
Re:Toolz: A functional standard library for Python by robertlagrant on Thursday January 21, 2021 @05:06PM (#25865079)
Yes, because gross.
Re:Toolz: A functional standard library for Python by dragonwriter on Thursday January 21, 2021 @06:08PM (#25865880)
Nor, IMO, should you want to.
Re:Toolz: A functional standard library for Python by throwaway894345 on Friday January 22, 2021 @08:44AM (#25871569)
Why not? Many other languages have closures and even Python has lambdas. Multi-line closures work well for these languages including in map/reduce/etc or comprehensions where applicable. Seems like your preference is overfit to Python’s limitations.
Re:Toolz: A functional standard library for Python by robertlagrant on Friday February 05, 2021 @03:15AM (#26034176)
Because you can do it in a function. It's not a limitation when you can do it. Having to define a function that's easier to read, and testable as an independent unit, is not a problem.
Re:Toolz: A functional standard library for Python by pansa2 on Thursday January 21, 2021 @02:59PM (#25863424)
I don’t think this limitation is likely to change - the only ways to allow whitespace-sensitive statements inside an argument list are all really ugly.
Re:Toolz: A functional standard library for Python by tda on Friday January 22, 2021 @02:22AM (#25869318)
If you really want though, you can write a web server in a single python lambda:

    (lambda flask:
        (lambda app:
            (app,
            app.route('/')(
                lambda: 'Hello World!'
            )
            )[0]
        )(flask.Flask('__name__')).run()
    )(__import__('flask'))
See https://gist.github.com/e000/1023982 for more horrible examples
Re:Toolz: A functional standard library for Python by heavyset_go on Friday January 22, 2021 @09:38PM (#25879032)
I hate it, but it is clever.
Re:Toolz: A functional standard library for Python by fwip on Thursday January 21, 2021 @03:28PM (#25863779)
You can do multiple lines, just not multiple statements:

    >>> f = lambda x: x * \
    ...  20
    >>>
    >>> f
    <function <lambda> at 0x7f8b69f2c6a8>
    >>> f(2)
    40
Re:Toolz: A functional standard library for Python by pansa2 on Thursday January 21, 2021 @03:37PM (#25863911)
In fact, no statements at all - just a single expression.
Re:Toolz: A functional standard library for Python by Iwan-Zotow on Friday January 22, 2021 @12:11AM (#25868541)
well, you could pack a lot of other expressions into that expression, especially with 3.8/3.9, e.g.

x,y = 1,2

q = list(map(lambda t: (tx := t*x, ty := t*y, tx+ty)[-1], [1, 2, 3]))

Re:Toolz: A functional standard library for Python by pansa2 on Friday January 22, 2021 @03:22AM (#25869591)
Walrus operator: not even once.
Re:Toolz: A functional standard library for Python by Iwan-Zotow on Saturday January 23, 2021 @12:34PM (#25884293)
walrus, actually, being an expression, it's a perfect fit for lambdas
Re:Toolz: A functional standard library for Python by scott_russell on Thursday January 21, 2021 @05:22PM (#25865280)
Agreed. I suspect that most uses of python decorators become moot with proper multi-line anonymous functions. I assume some would argue that decorators create more readable code but they seemed like a syntax hack to me.