Live data from Hacker News

Functional Programming in Python

github.com

21–30 of 64 posts

Re: Functional Programming in Python

#21

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 twiste…

I'd like to know what happens to can_buy_stuff and the rest of the code when user is Not None and balance_credit is -1.

Re: Functional Programming in Python

#22

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 twiste…

I'd like to know what happens to can_buy_stuff and the rest of the code when user is Not None and balance_credit is -1.

can_buy_stuff is then False.

Re: Functional Programming in Python

#23
post #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…

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.

Re: Functional Programming in Python

#24
For 'Maybe' an 'Result' specifically, I feel that Python builtins + mypy offer superior experience: easier, safer, and less dependencies with a similar level of verbosity.

For Maybe example: I think this 'functional' style with fmaps in Python is problematic, because lambdas can't be multiline. If you have sevearal lines of logic, you'd need an auxiliary helper def, and at this point it becomes as unreadable.

For Results: I think returning Union[Exception, Value] (where Value is the 'desired' type) and then using isinstance(result, Exception) is much cleaner.

- it can be statically checked with mypy to ensure the same level of type safety as Rust would have

- minimal performance impact

- no extra wrapping and unwrapping in the code. You can completely ignore mypy and error handling, until you're happy, then you harden your program by making sure it complies to mypy.

- no extra dependencies, third party code dealing with your library doesn't have to deal with your wrappers! If they don't check for error type, when Exception is encountered, the program will most likely terminate with AttributeError, which is a desirable behaviour in such situation.

- it's much easier to compose: propagating error with a decorator is neat, until you have some more sophisticated logic, e.g. for error aggregation

- the only downside is that you end up with occasional `if isinstance(result, Exception)...`.

I reviewed results library specifically here [0] and elaborate on different error handling techniques in Python, including the approach I described.

[0] https://beepb00p.xyz/mypy-error-handling.html#container

Re: Functional Programming in Python

#26

Why the lambdas at all in these examples... (lambda real_user: real_user.get_balance()) and not User.get_balance (besides subclasses not getting their balance called...)

It's a bad example. You can of course do more with lambdas in python. Maybe "lambda real_user: real_user.get_balance()+1" or "lambda some_junk, real_user: real_user.get_balance()" would have been better.

Re: Functional Programming in Python

#27

If there was one thing I'd change with python to make it more 'functional' it would be having lambdas that weren't expression-only. I know it's not a functional feature because it's for stateful programming, but the lack of it disallows some nice stuff.

lambda use in Python is discouraged in general. If you need something beyond an expression, PEP-8 encourages you to use a def in that case instead.

Re: Functional Programming in Python

#28

For 'Maybe' an 'Result' specifically, I feel that Python builtins + mypy offer superior experience: easier, safer, and less dependencies with a similar level of verbosity. For Maybe example: I think this 'functional' style with fmaps in Python is problematic, because lambdas can't be multiline. If you have sevearal lines of logic, you'd need an auxiliary helper def, and at this point it becomes as unreadable. For Res…

Lambdas can be multiline/multistep, but it's just as ugly as you'd expect. Maybe the most "pure" functional way to do it is to have multiple binds/applies/maps, so instead of something like `x=1; y=2; x + y` it's something like `1.apply(lambda x: 2.apply(lambda y: x + y)).` Still unreadable, but for different reasons. It's more about the grossness of using `xEmitter.map(lambda x: stuff with x in scope)` to bind x as a variable than it is about the inflexibility of lambdas.

Re: Functional Programming in Python

#30
post #8

If there was one thing I'd change with python to make it more 'functional' it would be having lambdas that weren't expression-only. I know it's not a functional feature because it's for stateful programming, but the lack of it disallows some nice stuff.

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…

very quick reply, and I've done this in other langs that allow procedures-done-as-lambdas, create your own control flow mechanisms with 'reasonable' syntax, something like

  with_file("c:/blah/data.csv", lambda fl:
    # do stuff with file variable fl
    # other statements
    # ...
  )
The file is opened, the block of code of the lambda does its thing, the file is closed at the end, exception-safe.

Python can do this another way (with 'with' objects or something, and it's quite clean and neat, but that's quite recent IIRC), this simpler IMO. Have used this, it's called the loan pattern, in scala, vb.net and C#, and prob others.

The arbitrary restriction on lambdas blocks composability, which disallows useful tricks like this.

Post reply on HN