Death to Type Classes
Posted4 months agoActive4 months ago
jappie.meTechstoryHigh profile
controversialmixed
Debate
80/100
Functional ProgrammingHaskellOcamlType Classes
Key topics
Functional Programming
Haskell
Ocaml
Type Classes
The article 'Death to type classes' explores an alternative way to structure code in Haskell using OCaml's module system, sparking a discussion on the merits and drawbacks of type classes and functional programming.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
3d
Peak period
36
72-84h
Avg / period
9.7
Comment distribution58 data points
Loading chart...
Based on 58 loaded comments
Key moments
- 01Story posted
Sep 12, 2025 at 7:46 AM EDT
4 months ago
Step 01 - 02First comment
Sep 15, 2025 at 2:53 AM EDT
3d after posting
Step 02 - 03Peak activity
36 comments in 72-84h
Hottest window of the conversation
Step 03 - 04Latest activity
Sep 19, 2025 at 4:48 PM EDT
4 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45221112Type: storyLast synced: 11/20/2025, 5:51:32 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
(I have a t-shirt with a lambda in a circle, reminiscent of the anarchist emblem, and words "no class, no state". It's definitely possible to explain to a passer-by who never studied FP what it refers to, but not in such a way that the joke remained funny. Possibly the same deal is with the bumper sticker saying "my other car is cdr".)
[0] https://etcsl.orinst.ox.ac.uk/proverbs/t.6.1.05.html#t6105.p... [1] https://knowyourmeme.com/memes/no-take-only-throw
How often do people think you're a Half-Life fan instead?
[1]: https://en.wikipedia.org/wiki/Gordon_Freeman#/media/File:Gor...
[2]: https://en.wikipedia.org/wiki/Anarchist_symbolism#/media/Fil...
And I wouldn't be surprised if there were more retired left handed surgeons in their 50s living in rural Switzerland than people who understand what he's talking about.
The author then uses Backpacks to achieve ad-hoc polymorphism without typeclasses.
There is a well-known article from a long time ago which was conceptually similar: https://www.haskellforall.com/2012/05/scrap-your-type-classe...
Which highlighted the fact that typeclasses can basically be thought of as an additional vtable argument passed to every function that has typeclass constraints. (And, indeed, thinking about them this way often allows one to avoid typeclasses entirely and achieve the same kind of polymorphism in simpler and more flexible ways.)
Backpacks can achieve something similar, except by declaring an abstract "signature" for your dependency, rather than a function argument. (Backpacks can also be used to do a lot more than this, of course, but that's outside the scope of the OP article.)
There has always been a sort of fascination with effect systems and dependency inversion in the Haskell community. You cannot throw a stone in any discussion board without hitting someone currently noodling on the problem of "man, typeclasses are cumbersome and don't compose well. What if we had something better?"
Transformers and mtl were the name of the game for a long time. Then for a while there was a LOT of hype around free monads and algebraic effect systems. When I was deeply into Haskell, at the time it sometimes felt like a new effect system library was being released every week.
Then there was also this counter-movement of people going "all this new-fangled stuff is overly complicated. Why don't we just use plain functions?" (see [0]).
And there were also a lot of people saying "well, if you just write your whole application in ReaderT IO, you can get 90% of the effects juice for only 10% of the complexity squeeze" (see [1]).
Meanwhile, this whole time we have had distant voices in the back pointing out that OCaml has already solved this problem, and Haskell should just introduce a feature for first-class modules. Well, now it's here, and it's called Backpack.
[0]: https://www.simplehaskell.org/
[1]: https://academy.fpblock.com/blog/2017/06/readert-design-patt...
I think 90% is an overestimate because you don't get any encapsulation. Maybe 50% is a more reasonable number. If you want 99% of the effects juice for 1% of the complexity squeeze, my effect system, Bluefin0[1], as well as the effectful[2] effect system
My recent talk "A History of Effect systems"[3] explains this in more detail, as does the "Why even use an effect system"[4] section of the latest Bluefin documentation.
[1] https://hackage-content.haskell.org/package/bluefin
[2] https://hackage-content.haskell.org/package/effectful
[3] https://www.youtube.com/watch?v=RsTuy1jXQ6Y
[4] https://hackage-content.haskell.org/package/bluefin-0.0.17.0...
I can tell this is article is about a common, wide debate in CS; should languages have "strict" structures like type class or loose structures like "objects". This related-to but not the same as the debate on whether to have pure functional languages or ad-hoc imperative languages.
I know in programming practice, everything ad-hoc has won but programming language "theory", everything strict has won.
Now in this context, I understand the post as advocating a certain kind of loose data typing with the strict-world of Haskell. Which I'd imagine won't make any ideologue happy. But seems like an OK contribution to the debate.
To add my own takes on everything, as hners must do, I think the strict structures of functional programming have quite a bit of merit for various purposes. BUT - they aren't intuitive/the-easy-way-to-everything-once-you-know/etc. AND they aren't a way to solve the software crisis.
I've been doing a lot of parsing lately and I find I don't need to reach all the way for monad (applicative is usually enough). But I guess that's what ApplicativeDo[1] is for.
This is a bit rough for usability (not to mention also undermines the point above).But overall I like the approach of trying something radically new.
[1] https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/appl...
*: By "possibly parallel" I mean the blocks of code are known to be independent from each other. They could be actually executed in parallel if the Applicative instance does so.
If the Applicative class chooses to decide randomly whether to run in parallel, that's the class's fault, not the language or the compiler's problem.
That era is now over.
And honestly, I don't see the point there either. I know that backpack is meant to solve some problem everybody has, but I haven't been able to fully understand what that problem is. Specifically on this article, I don't see the gain over using a type class.
The blog post is an exploration of an alternative way to structure code in Haskell.
Why is the bar such that Haskell blog posts have to either demonstrate something clearly better then the status quo or that they need to explain the fundamentals of the language?
It's fine for, say, a blog post aimed at Haskellers to assume Haskell knowledge, but when posted on a board largely consisting of people without Haskell knowledge, it's natural that you're going to get at least a few people saying, "hey, I don't understand this".
But I'll be honest - I'm familiar with Haskell and the ML module system and the underlying concept (that typeclasses and modules are roughly equivalent in some sense), but I'm unfamiliar with Backpack so I still struggled to follow it a little. The target audience is an extremely narrow niche. So I think it's just somewhat poorly written; it doesn't feel like the author really had an audience in mind, other than themselves. There's probably ways of writing this - without spending too much time regurgitating the basics - that would be more palatable to more people.
I hear you on this point but anyone can post anything on this forum. The burden should not be on the author to write a post that aligns with whatever forum their blog might get posted onto.
(don't @ me with your pedantic bullshit about how types and classes are different, I don't care).
Personally, just from reading the title, I was hoping for an article about the design of type systems in programming languages in general.
The key to this is that modules in ML are actually kind of a separate programming language. Not only can you define modules, you can define "functor modules" - modules that are kind of like functions; you can pass modules as arguments to functors to produce new modules. And there's a (structural!) type system here, too: the modules a functor can accept are specified to have a specific structure, and if you try to pass an incompatible module to a functor you get a type error.
(Incidentally: the naming of functors in the module system is really unfortunate here, because it overlaps with the name of functors in category theory/Haskell.)
This sounds extremely abstract and kind of insane; it's easier to understand it in practice. A typical example might be that you want to define a hash table, which requires some kind of hash operation for a key. What you'd do idiomatically in ML is define a HashTable functor which takes, as an argument, a module X consisting of a type t and and a hash function. This would generate a HashTable(X) module specialized to that particular key type.
What's interesting here is that there's an overlap here with things like interfaces in Java or typeclasses in Haskell, where your HashTable type would demand that the key type adheres to a Hashable interface. It turns out they're kind of (kind of!) just different takes on the same thing. There's even some interest in the OCaml world in trying to "close the gap" with a feature called "modular implicits" [0].
The other thing to know is that there's an esoteric feature of Haskell called "Backpack", which is an attempt to bring the ML module system to Haskell. It's not exactly widely used or anything like that, but it's there and been in GHC for several years now.
This article is basically just demonstrating how Backpack lets you use modules in much the same way as you'd traditionally use typeclasses in Haskell.
[0] https://www.cl.cam.ac.uk/~jdy22/papers/modular-implicits.pdf
Assuming `IO.readFile` and `IO.writeFile` is replaced by HTTP requests. I can define `writeFile` and `readFile` in a type class and then implement the effect for HTTP variant, hiding the HTTP client beneath.
Is it just wiring it up in mixins, cabal file?
I think general conclusion is that there's no need for dependency injection, environment objects, or similar tricks if module system is rich enough.
For a long time I questioned why Python needs anything but `async def` or `def` (async should be achievable through module or `yield` usage) and `import` statements, to achieve maximal reuse, given dynamic nature of language and modules. We could ignore all object-oriented features, decorators, replace them with modules. Would be flatter and readable compared to bloated feature set.
17 more comments available on Hacker News