Live data from Hacker News

Functional Programming in Python

github.com

11–20 of 64 posts

Re: Functional Programming in Python

#11
This is neat. It reminds me of an silly project [0] I made a while back to implement do-notation in python. In OP's project you still end up with code that's basically this:

    y = (Maybe(just=x) if x > 0 else Maybe()).bind(lambda a:
         Maybe(just=x*a)                     .bind(lambda b:
         Maybe.mreturn(a+b)))
It's functionally sound and standard, but ergonomically painful. I built a really fun horrible hack to allow you to write that instead as this:

    with do(Maybe) as y:
        a = Maybe(just=x) if x > 0 else Maybe()
        b = Maybe(just=x*a)
        mreturn(a+b)
It swaps out the assignment operator `=` in the `with do()` block for the monadic bind operation, which you might be used to seeing as `You just need to use my @with_do_notation decorator, which just completely rewrites your function using the ast library wherever it finds a block of `with do(SomeClass) as variable:`. I was even able to write ergonomically nice parser combinators [1] that would actually work pretty well if python had tail call optimization.

You shouldn't use it but it was great fun and opened my eyes to the ways you can abuse python if you really wanted to. Using decorators to introspect and completely rewrite functions is a fun exercise.

[0] https://github.com/imh/python_do_notation

[1] https://github.com/imh/python_do_notation/blob/master/parser...

Re: Functional Programming in Python

#13
How about writting modern and proper Python first? Not to mention designing a decent API?

Let's examine the README example for a minute:

    user: Optional[User]

    if user is not None:
         balance = user.get_balance()
         if balance is not None:
             balance_credit = balance.credit_amount()
             if balance_credit is not None and balance_credit > 0:
                 can_buy_stuff = True
    else:
        can_buy_stuff = False
I don't know if it's been deliberatly twisted, but that's not what I would called idiomatic or realistic for a Python program:

- one should probably never reach this part of the code if there is no user. But I'll indulge the author.

- don't put can_buy_stuff in an else close, what's the point?

- using type hints for no reason, but not other modern facilities like the walrus operator?

- do we really want users without a balance? Let's indulge this, but it seems a bad design.

- what's with all those unecessary conditional blocks?

- credit_amount should never be None. It's a Balance object, put a sane default value. But ok, indulging again.

So, you get down to:

    user: Optional[User]   
    can_buy_stuff = False  
    if user and (balance := user.get_balance()): 
       can_buy_stuff = (balance.credit_amount() or 0) > 0  
I don't think the solution the lib offers is superior:

    can_buy_stuff: Maybe[bool] = Maybe.from_value(user).map(  
        lambda real_user: real_user.get_balance(),
    ).map(
        lambda balance: balance.credit_amount(),
    ).map(
        lambda balance_credit: balance_credit > 0,
    )
And that's if we are using the rules of the README, which are not fair.

If we have a well designed API, and we use a function (more testable, and hey, are we doing FP or not ?), then:

    def can_buy_stuff(user: User):  
        if (balance := user.get_balance()):
            return balance.credit_amount() > 0
        return False
Checking the user should not be part of this algo, credit_amount should be 0 if never set. We could even remove return False, I keep it because I like explicitness.

You could even that as a method or raise NoBalance depending of your case.

Bottom line, if you really feel that strongly about None, don't jump on the bazooka to kill this fly, go to https://discuss.python.org and advocate for PEP 505 (None-aware operators): https://www.python.org/dev/peps/pep-0505/

It's been deferred since 2015.

That doesn't mean we should not experiment with other paradigms in Python, and I do think this lib is an interesting experiment, but I don't find it conclusive.

Re: Functional Programming in Python

#15
post #11

This is neat. It reminds me of an silly project [0] I made a while back to implement do-notation in python. In OP's project you still end up with code that's basically this: y = (Maybe(just=x) if x > 0 else Maybe()).bind(lambda a: Maybe(just=x*a) .bind(lambda b: Maybe.mreturn(a+b))) It's functionally sound and standard, but ergonomically painful. I built a really fun horrible hack to allow you to write that instead a…

Cool hack – not because I want monads in Python particularly, but because I sometimes think a ‘where’ syntax would be nice

Re: Functional Programming in Python

#17
can't say i'm a fan of the decorator to implement functional concepts. jut feels dirty. type hints in python are just as meh. feels like it's not taking advantage of pythons duck typing.

a version of try and either, with a decent do notation taking advantage of for comprehension... https://github.com/papaver/pyfnz

Re: Functional Programming in Python

#19
post #2

Why would you want to use the I/O monad in Python?

A big reason to use IO as a value (which IMO is a better name than IO monad), is the same in all languages: reasoning about immutable values is easier than side effects. If we can take complex IO operations and use composition tools exactly the same as other immutable values, it’s very nice.

Of course, in my experience, this is so foreign to people who haven’t worked with it for a time it is very difficult to sell in small reply.

Re: Functional Programming in Python

#20
post #17

can't say i'm a fan of the decorator to implement functional concepts. jut feels dirty. type hints in python are just as meh. feels like it's not taking advantage of pythons duck typing. a version of try and either, with a decent do notation taking advantage of for comprehension... https://github.com/papaver/pyfnz

I think if that some of these concepts should just be included with the 3.9 Annotated Type

    Annotated[IO[str], unpure]
in 3.9 and above if the authors want to commit to type hints being core to this. I agree that the decorators feel a little wrong
Post reply on HN