Live data from Hacker News

Functional Programming in Python

github.com

51–60 of 64 posts

Re: Functional Programming in Python

#51
post #39
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…

Your example isn't using "y", so you should also be able to drop the " as y" part (unless the AST hack requires it for some reason). Edit: Oh, nevermind - the "y" is how you access it after the with statement. Weird for python, but it makes sense given the rewritten version. I was thinking your version would have a non-rewritten "result = something " within the with block in a real use, but that's not what it's doing…

Heh, yup, it's part of the hackiness of it all. "with do(MyMonadClass) as my_variable: " equates to haskell's "myVariable = do ". I can't remember why the MyMonadClass part was necessary. Maybe for the mreturn.

Re: Functional Programming in Python

#52
Functional programming in Python:

Step 1: try to integrate more functional methods in your current Python programming due to their usefulness.

Step 2: get increasingly frustrated, and then give up, because Guido and the Python devs seemingly hate functional programming and keep hobbling it.

Re: Functional Programming in Python

#53
post #43

I'm a big fan of functional programming but this documentation is kind of funny, unintentionally. I realize there is no better way to do it in Python. And that’s how your initial refactored code will look like: user: Optional[User] can_buy_stuff: Maybe[bool] = Maybe.from_value(user).map( # type hint is not required lambda real_user: real_user.get_balance(), ).map( lambda balance: balance.credit_amount(), ).map( lambd…

I'm also a FP fanboy, and this concept doesn't quite convince me. I'm not sure a Maybe type really helps that much in a dynamically typed language. All the safety you get from using Maybes is worth Nothing (pun intended) when credit_amount could still return let's say Just a string, or raises an exception.

If this chain of calls supposedly handles Nones at any level, then .map is not the right method. It should be .flatMap (or .bind). Unless this is a magic .map that handles either X or Maybe[X] and even exceptions (just like JS promises). This flexibility may be convenient and I can appreciate its pythonicness, but it's not really in the spirit of typed FP.

Re: Functional Programming in Python

#54
post #19

Earlier quoted context omitted.

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…

We have coroutines for that: it delegates any blocking behavior to outside of your code. Introducing a new paradigm while this one just got in would be overkill IMO.

That's why a lot of functional language research is moving towards effect handlers, which could be explained in a nutshell as "coroutines, but for anything"

Re: Functional Programming in Python

#55
post #25
post #18

The `Maybe` container seems to be a close analog of `Option` in Rust https://doc.rust-lang.org/rust-by-example/std/option.html

Another synonym is Some in some languages.

WellActually™, Some is a synonym of Just, Maybe is a synonym of Option, and Nothing is a synonym of None.

Re: Functional Programming in Python

#57
post #45

> But, having null checks here and there makes your code unreadable. 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 Actually I think that's very readable user: Optional[User] can_buy_stuff: Maybe[bool] = Maybe.from_value(user).map( # type hint is no…

Yeah, I'd much rather read this:

    def can_buy_stuff(user):
        if user is None:
            return False
        balance = user.get_balance()
        if balance is None:
            return False
        balance_credit = balance.credit_amount()
        if balance_credit is None:
            return False
        return balance_credit > 0
Edit: something like Swift's optionals and nil-coalescing syntax might make this easier to read:

   def can_buy_stuff(user):
       return (user?.get_balance()?.credit_amount() ?? 0) > 0

Re: Functional Programming in Python

#58

Python + Functional = http://coconut-lang.org/

As a language purist this one is surprisingly well put together. Its impl suffers from legacy (py2 support in general, predating builtin dataclasses, staying in the shallow end of type annotations) but it really does what it does better enough than its host language to be worth giving attention to. Check it out.

Re: Functional Programming in Python

#59
post #8

Earlier quoted context omitted.

I agree with you that having more than a single expression in lambdas would be super nice. That being said, I don't think it's necessarily stateful to allow more than a single expression! If you don't reassign any variables, then it's equivalent to a single expression. For instance, something like this (using made up syntax for extended lambdas) isn't stateful: lambda i: square = i * i if i A decent heuristic for whe…

I'm sure there are cases where multiple lines would be nice, but I don't think this is one. This seems easier to read to me: lambda i: -i * i if i Also, the functional way of doing multiple lines in a lot of situations would typically be to compose smaller lambdas.

And there is math.copysign

Re: Functional Programming in Python

#60

Functional programming in Python: Step 1: try to integrate more functional methods in your current Python programming due to their usefulness. Step 2: get increasingly frustrated, and then give up, because Guido and the Python devs seemingly hate functional programming and keep hobbling it.

A part of me is happy to see these types of tools introduced to python, but another part makes me wonder why people continue to use python when they see the value of things like `Option`/`Maybe`'s, `Result`'s, instead of just using a language with the features included from the start.

In my experience, the initial ease and speed of development when using python doesn't nearly outweigh the medium to long-term costs of maintaining it and developing the codebase further - at least for codebases that are more than a simple tool or something like a django app. Writing things like go, rust, scala, java etc. isn't that much more difficult or slower, but it does require more up front planning and understanding of your problem domain.

Post reply on HN