I’ll come out and say it though: Haskell is a cult. It’s best to smile and nod when you’re around the believers. They’re harmless. Ditto for rust.
It is truly astonishing how much code a determined team of haskellers can produce. I’ve been porting a codebase, line by line, to python. I’m up to 15 thousand lines.
Had to do it without being able to run the program too.
There are lots of benefits. (Ditto for being in a cult.) It’s worth knowing what they are, since they are powerful. But (hello cult) there are plenty of negatives; monads are the Aristotle philosophy equivalent of programming. Take care not to study them too closely.
Breaking down the benefits of each:
- Expressive: you can model things with greater fidelity
- Pure: you know when your code performs side effects, so you're in for fewer surprises
- Statically typed: you learn about things at compile time, not in production. You also need to write fewer tests.
- Large pkg registry: fewer things to implement yourself (compared to, say, Idris)
- Large community: fewer problems you'll be the first one to discover/solve
- Optimized enough compiler: compile times can be _acceptable_
- Optimized enough runtime: your app will be fast enough without you having to care much about it
Now one point that isn't obvious from all this and that is a big selling point for my company is how much of a breeze refactoring is. Types give you more guarantees around how your code behaves, so there's classes of mistakes you can't make, and won't have to rely on a super strict test suite to prevent you from making.
Newhire submitting a PR changing 25 files all over the codebase? Business as usual.
Take a vector package, for example. It provides you with unboxed vectors that are structure-of-arrays by default with the interface of array-of-structures. That means you can have fast slicing operations in both dimensions - slice by field and/or by indices. Of course you can have unboxed array-of-structure arrays, if you need them, they are there too. But their use is transparent to you as user, however your choice is.
Same is for other interesting structures.
Say you wrote your parsing library. You can provide a rule to compiler such that code "(pchar c `pthen` p1) <|> (pchar c `pthen` p2)" is equivalent to "pchar c `pthen` (p1 <|> p2)" and you get left factorization for all your grammars supported by compiler.
Parallelization is often as far away as adding a par/pseq annotation.
Haskell can remove intermediate lists and fuse mapping over complex structures such as red-black trees - it is done for all of your code so when you do "fmap f (fmap g) rbTree" you will get "fmap (f . g) rbTree" and compiler will try to get you that code by transforming your code where "fmap f" can be pretty far away from "fmap g rbTree".
The pattern matching checks are awesome - compiler will warn you if you wrote more general check before more specific one. The absence of this in C++ made my life a little bit more interesting than is comfortable for me.
In short, most of the time you can write code however you want or need and compiler will support you. As if you are "team programming" with a bunch of smart people - the compiler's authors.
Functional programming allows a great deal of confidence in your code,
Sorry for being off topic: the new M1 Macs seem to take some of the pain out of large runtimes for compile/build in languages like Haskell and Swift. I don’t have any benchmarks, this is just very noticeable when I am coding.
I chose Haskell to develop sumi.news because I enjoy programming in it, and because I don't want to worry about type errors and crashes at runtime.
> Does it offer any actual practical benefits over other languages?
Haskell offers a more expressive type system than other languages.
There were some practical reasons for this, but at the end of the day: if you're going to spend thousands of hours developing something, you might as well choose a language that you find beautiful and enjoy working in.
* embedded DSL for describing things with minimal syntax * types to enforce my invariants * immutable data + STM to protect my shared data structures * multithreaded/async code is easy to work with * deterministic outputs given inputs
but it was headaches in a lot of ways:
* exceptions - still not sure I’ve handled all exceptions gracefully * culture - most teammates are intimidated by Haskell (and types) * ecosystem is behind (Rust has exponential usb acceleration vs Haskell’s constant pace)
While I’m proud of the outcome I would have chosen differently now that I’ve seen the other side and have the project done. The inertia I was fighting required far too much energy
Actually ImplicitCAD is written in Haskell which implements CSG (very tricky to efficiently implement)
Haskell is fast, compiled, type safe, memory optimized, allows concurrency and parallelism. The use cases where you'll see using Haskell will generally be companies like financial sector where very fast and error free execution directly translates to making more money, e.g. dark pool front running trading algorithms. Generally you don't hear it extolled because of who is using it and the secrecy around what it's being used for, e.g. competitive advantage.
Outside of that you'll probably only see it in academia because of a lot of the reasons listed in the replies. In my opinion its a harder language to learn because it really is just lambda calculus translated to a programming language.
It offers less and less practical benefits over other languages because other languages evolve to where Haskell has been.
Haskell is correct, and it forces you to be correct and enforces a kind of clarity of thought that is seldom required from other languages. I think it's something you have to discover for yourself. If you don't see Typescript as strictly better than Javascript, you're probably not going to see the benefits of Haskell over any other language.
All that said, we have to ask ourselves which areas of computing Haskell can be profitably used in to gain the kind of critical mass that other languages have:
- Early programming, analysis, data science, etc -> Python is a better fit because it's easier to pick up, easier to understand, even though it's less correct. People discover libraries about checking types at runtime before they discover then can check them at compile time. Python has long since started it's evolution w/ the typing module.
- Web -> JS, because it's basically the only option. Projects like Elm and Purescript have made small dents, but the most successful cultural descendant of Haskell (if you can call it that) is Typescript.
- Startups -> Ruby/Rails, Django, NestJS, etc. win over Haskell here because you don't need to be right to have a successful startup, you need to find customers and after that product-market fit. Your startup could be airflow+google sheets with all-manual validation and still succeed over the most carefully crafted and bullet proof Haskell code.
- Safety critical systems -> Often are required to be realtime and it's easier to get to the safety requirements in other low level languages with strict procedure/process/standards and guaranteed realtime-capable OSes and tooling rather than using Haskell.
I've written about Haskell in the past (excuse the title):
Binary size is small..
And very important to me they could be executed even years after they were first uploaded to Rosetta code.
A very good study and the researches gave an entertaining talk on it, that I can't find now.
It sure does. Perhaps you should try it?