No More Haskell for Me
August 1, 2020
Defining what it means to “know” a programming language is not an easy task. For the purpose of this post, let’s say it means feeling comfortable enough to write a moderately complicated program while looking up information occasionally. As luck would have it, I know quite a few languages when defined this way, but I always wanted to learn more. Haskell was, for a long time, one of the languages I knew I would learn “someday.”
By frequenting sites like Reddit or HN, you’ll find numerous articles about Monads, Lenses, Effects, Transformers, and other intriguing concepts. It’s not difficult to get sucked into that world, especially if you have a curious mind.
Over the past few years, I’ve attempted to make progress in learning Haskell, but it wasn’t until 2020 that things finally started to click for me. I worked on two medium-sized projects and enjoyed learning new things.
However, even with 13+ years of professional experience and months of working with Haskell after hours, writing working code remained incredibly challenging. In fact, if it were any other language, I would have given up long ago. But with Haskell, I convinced myself that I needed to figure it out.
There are numerous videos and research papers where Haskell is the language of choice, as well as many advanced concepts like Dependent Types, which are much easier to understand if you know Haskell well. Discovering all of this can be both awe-inspiring and overwhelming. To truly grasp these concepts, you need to invest time and brainpower. This allure, however, makes it even more attractive to geeks like myself.
After learning some of what Haskell has to offer, it’s natural to try and apply that knowledge in your work. However, much of it is so cutting-edge that it’s not yet ready for practical application.
Often, it’s difficult—if not impossible—to identify canonical implementations for concepts like monad transformers or effects. The existing implementations require even more time before you feel comfortable using them.
I’ve found that a significant portion of my time has been spent grappling with the language’s type system, rather than working on domain-specific problems. Haskell’s type system, while powerful and expressive, can often feel unwieldy and complex, leading to a steep learning curve. Moreover, the available tools and libraries for working with Haskell are not as comprehensive or user-friendly as those for more mainstream languages, making it even more challenging to navigate the type system efficiently. Consequently, the process of writing and debugging Haskell code can sometimes be slower and more time-consuming, as you find yourself frequently troubleshooting type-related issues instead of focusing on the core logic of your application.
Because of things like that my opinion right now is that Haskell is a nice language to learn and treat is as tool for thinking about programming and research. But it’s not very practical. When I say practical I mean it’s not a good choice for most of the programmers doing most of the programming jobs in the real world.
Things like Maybe, Either… in the begining I was in love with those concetps but the more I used them the more I noticed the trade-offs:
- Hickey in “Maybe Not” says it right, what does it mean that we have “Maybe Sheep” ? We either have it or we don’t.
- Either.. this is cheating - moving OR to userspace… when you use Either Right it is supposed to hold the correct value… that just seems so hacky
- Monads… well this is a good idea but it had to be found because the language would be unusable otherwise… Instead of IO we just could have used
try ... catch
- Monad transformers.. effects… more of the same… complex stuff added because the purity is valued too much. Instead, I’d prefer to focus on data immutability and allow side effects.
- Lenses - I’m not sure.. but that might be the straw that broke camels back… so much coded added just because the Records are comletely broken
- Every new library means you need to learn all types and their algebra… and there is very little experimentation to be done - I mean you can’t have partial data in REPL, you have to match the whole type and it’s values You can partially apply the type but that is just the type to have an instance to play with you need the whole thing
- Yeah it’s easier to refactor stuff, and mostly it boils down to fixing some type declarations, but well structured code in even imperative dynamic languages is not that bad in that regard as well - I just don’t think this is such a huge benefit - maybe for people that can’t write well structured code or “don’t belive in tests”
Of course Haskell teaches you many things the one that will stay for me is the separation of types and values, and especially the fact that you can have behavior in both values and types.
Sooo am I “liberated” from the idea of becomind a Haskeller one day? I think mostly yes, but if I don’t stop reading those cool blog posts and research articles things might change in the future and I might get sucked right back in.