4 ms·
I really wasn't trying to compare Python to Haskell, rather I was trying to show a few example features in Haskell with the Python code as a reference for the "
by oisdk 7y ago
I really wasn't trying to compare Python to Haskell, rather I was trying to show a few example features in Haskell with the Python code as a reference for the "standard" way to do a binary tree type thing. Other than the (admittedly awful) `__dict__` stuff, the rest of it is pretty standard. In contrast, the code you've written here is non-mutating, and uses tuples to represent a tree. If you were to google, say, "BST in Python" I'd wager almost none of the implementations would follow that style. If I was to write a skew heap in Python (that I intended to use), I would likely do it in a non-mutating way (although I certainly wouldn't use tuples and `leaf = object()`).
The point of the post was really to argue that simple features like pattern matching, ADTs, and so on, should be in languages like Python and Go. Also I wanted to make the point that functional non-mutating APIs could be simple and tend to compose well: the `unfoldr` example was all about that. In that vein, it was important that I compare the Haskell code to an imperative version.
For instance, with your `reduce` improvement: I agree that the `reduce` version is better! It's simpler, cleaner, and easier to read. But Python these days is moving away from that sort of thing: `reduce` has been removed from the top-level available functions, and you're discouraged from using it as much as possible. The point I was making is that I think that move is a bad one.
Finally, while the Python code here is shorter, you still don't get any of the benefits of pattern-matching and ADTs.
* You can only deal with 2 cases cleanly (what if you wanted a separate case for the singleton tree?).
* You are not prevented from accessing unavailable fields.
* You don't get any exhaustiveness checking.
- lidHanteyk 7y agoPython has some basic pattern matching. ADTs are alright, but if you notice that MLs implement them by tagged unions, then really this is a request for syntax and ergonomics, not semantics. Python is untyped. This fundamental separation between Python and Haskell is non-trivial, and can't be papered over. Your complaints about exhaustiveness, field existence, and case analysis are all ultimately about the fact that Python's type system is open for modification, while Haskell's is closed; in Haskell, we can put our foot down and insist that whatever we see is an instance of something that we've heard of, but in Python, this is simply not possible. I agree, when it comes to Python's moves. I am about ready to leave Python 2, but I'm not going to Python 3.
- oisdk 7y agoWhile I am all for stronger type systems, I don't agree that you need it to do sum types. We can already do one half of ADTs (classes ~= product types), I just want the other half! In my mind, the syntax would be something like this: sum_class Tree: case Leaf: pass case Node: data: Any left: Tree right: Tree def size(tree): case(Tree) tree of: Leaf: return 0 Node(_, left, right): return 1 + size(left) + size(right) A combination of data classes and pattern matching.