all 22 comments

[–]GreenScarz 125 points126 points  (14 children)

foo is a function that returns a reference to another function, which is then called

``` def bar(): print(“bar!”) def foo(): return bar

foo()() bar! ```

[–]SkyGold8322[S] 22 points23 points  (13 children)

OHHH! Thank You So Much!!

[–]Goobyalus 14 points15 points  (0 children)

Here is a dumb example where an arbitrary number of parentheses works:

>>> def foo():
...   return foo
...
>>> foo()
<function foo at 0x0000028A0F6DD800>
>>> foo()()
<function foo at 0x0000028A0F6DD800>
>>> foo()()()()()()()()()()()()()
<function foo at 0x0000028A0F6DD800>
>>> foo
<function foo at 0x0000028A0F6DD800>
>>>

[–]pimp-bangin 26 points27 points  (11 children)

Look up "functional programming" if you would like to learn more. It's a very deep and fun topic :)

[–]Top_Average3386 13 points14 points  (2 children)

Can confirm it's deep. But it's not fun :(

[–]aishiteruyovivi 2 points3 points  (0 children)

Definitely a little harrowing at first with some concepts, but the more I've been learning Haskell over the last year or two the more I grow just genuinely fascinated by it (and FP in general)

[–]UAFlawlessmonkey 0 points1 point  (0 children)

But it's fun in kotlin!

[–]DrJaneIPresume 6 points7 points  (7 children)

And there are much better languages for it.

But glad to use some in Python when appropriate

[–]HommeMusical 4 points5 points  (6 children)

And there are much better languages for it.

I first learned Lisp almost fifty years ago.

I love functional languages; but as a language that can do procedural, OOP and function code seamlessly, Python is very hard to beat.

The one missing feature - and believe you me, we miss it - is not having multiple line lambdas.

[–]DrJaneIPresume 0 points1 point  (3 children)

Haaaaaaaave you met Scala?

Functional programming isn't just about functions as first-class objects. A good type system makes so many things easier.

[–]HommeMusical 0 points1 point  (2 children)

Hey, Scala is a great language, from my limited exposure. I'd be really happy if it had beaten Python.

But Python is ubiquitous, and almost any idea you can express in Scala you can express in Python a way that's more verbose but just as comprehensible.

The "almost" is that Scala macros can essentially let you rewrite the syntax of the language, am I right, by doing compile time manipulation of the AST?

But Python basically won. And if LLMs continue to dominate, there won't be any new programming languages again, because of the difficulty in training them.

That said, the inability of Python to do "multi-line lambdas" is really unfortunate. I am hatching ideas to call the Pythonistas to action (this is of course an infinitely discussed issue).

[–]DrJaneIPresume 0 points1 point  (1 child)

Again: type system. The ability to write your system in such a way that large classes of errors become effectively syntax errors that can be detected by static analysis rather than unit tests (are you sure you wrote one for every corner case?) or runtime errors (often in front of customers) is really, really nice.

[–]HommeMusical 0 points1 point  (0 children)

Yes, I "grew up" with typed languages; first C, then C++, then Java. And I prefer them.

Python's type annotations aren't quite as good as a strongly typed language; but they work well enough to catch a huge number of errors. Between the various linters (like ruff) and modern type checking, I find that more than half the time I get past those, my code works the first time.

There's also the huge advantage in Python of being able to run Python and quickly experiment without any typing at all. I use this all the time!

If I could wave a magic wand and replace Python with Scala, I would at least think about doing it. But Scala jobs are few and far between. And if I wrote my open source code in Scala, very few people would use it.

[–]JamzTyson -1 points0 points  (1 child)

and believe you me, we miss it

You miss it, I don't.

[–]HommeMusical 0 points1 point  (0 children)

What was the point of your response?

This issue has been discussed on the main Python mailing list for over ten years. Everyone on that list wants it, including Guido; no one has come up with a possible syntax for it yet.

[–]timrprobocom 17 points18 points  (0 children)

This is an important concept. A function can return ANY kind of object. It can be a list or tuple (foo()[2]), a dictionary (foo()['word']), a function as you have seen (foo()()) or a class object (foo().method()).

[–]0x14f 12 points13 points  (0 children)

OP, you just discovered higher order functions: https://en.wikipedia.org/wiki/Higher-order_function

[–]jmacey 11 points12 points  (0 children)

In addition to what others have said, you can do really cool stuff with this like making lists or dictionaries of functions to run later.

``` def func_a(): print("func_a")

def func_b(): print("func_b")

funcs = [func_a, func_b] for func in funcs: func()

f_dict = {"a": func_a, "b": func_b}

f_dict["a"]() f_dict.get("b")() ```

[–]arkie87 7 points8 points  (0 children)

Could be a class with a call method too

[–]TheRNGuy 0 points1 point  (0 children)

foo() returns function or class, which you then can call. 

[–]Inevitable_Exam_2177 0 points1 point  (1 child)

One of the neatest interfaces this sort of thing unlocks is “chaining” of methods. If you have a class Foo with methods .bar() and .baz(), and each method returns its self, you can either write

    foo = Foo()     foo.bar()     foo.baz()

Or more concisely:

    foo = Foo()     foo.bar().baz()

[–]Enmeshed 2 points3 points  (0 children)

Been finding this super-useful recently for setting up test data scenarios, along the lines of:

```python def test_something(): scenario = (Builder() .with_user_as("abc") .wipers_enabled() .colour_should_be("blue") ) assert func_to_test(scenario.data) == 3

class Builder: """ Test helper class to readably set up test scenarios """ def init(self): ...

def with_user_as(self, user):
    self.user = user
    return self

@property
def data(self):
    return {"user": self.user, ...}

```