Hacker News new | ask | show | jobs
by bhy 1723 days ago
Python type checking (type annotation, mypy) should at least partially solve the problem of maintaining complex Python systems. Though it doesn't help with performance.
2 comments

The larger problem in my view is that big Python systems tend to follow OOP design since functional programming patterns do not work well in Python. So you start with something minimal and simple inside a script or notebook, but quickly it evolves into something more like a Java code-base.

Typing does help, agreed.

I strongly suggest the Attrs library for cutting down the boilerplate of making small "data classes": https://attrs.org/

With type annotations, you can move away from "inheritance OO" to logicless "data classes" and functions that operate on them.

Java has good to great FP, making most objects immutable is also trivial. Mypy is good to get strict typing enforced but, but I still prefer the native and slightly wonky typesystem to a tacked on one that builds on trust.
> Java has good to great FP

Java does absolutely not have "good to great FP" support. It's an imperative and OO programming language that recently got lambdas, no more, no less.

Yeah 100% - Java lacks many of the features required for serious FP and the ecosystem of libraries is heavily OOP too (although functional wrappers can usually be implemented).
There's sealed classes, records, pattern matching, optionals. It's getting there.
All good improvements, but Java is missing some really key pieces:

- pipe operator (or custom operators in general)

- do-notation

- tail call optimisation

- currying / partial application

- (better) type inference

- expression orientated

- less syntactic noise around function calls (fewer commas and parenthesis)

- type-classes or even runtime generic information to work around that

Some of the thing I’ve listed can never be added without dramatically changing what Java is. At that point it would be a new language.

I think you're moving the goalposts from "good to great FP support" to "is Haskell". I think that's the only one that fullfills both do-notation and tail call optimisation at the same time. Well, there's also Purescript and Scala.js running on JavaScriptCore since it has tail call optimisation, but that's a bit of a stretch. I see a lot of people like you that seem to have a very precise idea of what FP is supposed to be, and that idea always boils down to "basically Haskell". I think that's a fallacy, and that Haskell is not the only way to do FP. We have now languages like Koka, and soon (ish) OCaml that have effects, and are going to provide an alternative to Haskell's monads. There's also stuff like Scala with the DOT calculus. Lots of exciting stuff is happening in that space, and being a purist of one specific implementation isn't helping.

To get back to the subject of "good to great FP support", maybe we disagree fundamentally. Here are a few examples:

I would say that Rust is a good example of "great FP support". It's not a functional programming language, but it supports a lot of the patterns that make statically-typed functional programming languages effective. However, its DNA is still mostly "imperative programming language".

For "good FP support", I'd say TypeScript and C# are nice examples. C# has LINQ, pattern matching, records, optionals in a way. TypeScript has the usual JS stuff, plus the type system is nice. Both are lacking in some places. For example, in TypeScript/JavaScript, the usual map/reduce/filter are only functions on Array, and don't work with iterators.

To take the opposite view: what would be a functional programming language with good or great support for another paradigm? OCaml could be an example of good/great support for imperative programming. Scala has great functional programming and great object-oriented programming.

Works up until every function has a

  def calc_xxx(df:pandas.DataFrame) -> pd.DataFrame 

type...