If you'll forgive the analogy, Haskell is kind of like the Mercedes of production-ready research-grade languages. You may not actually use haskell, but the features that haskell is pioneering are what you'll see trickling down into other languages, as language designers look over and borrow things. Some examples (though they're not all invented by haskell, but haskell has popularized them IMO):
- non-nullable types
- immutability as a default
- typeclassses + structs
- abstract data types
- errors-as-values
- monads
Haskell or any other ML language didn't come up with all these things of course, but Haskell is one of the best languages
Take a look at rust -- it's basically got a near haskell-grade type system (and there are lots of ML languages with more flexible type systems than Haskell as well), with C++ like performance. It would have been a lot harder for rust's designers to incorporate such a nice type system without the exploratory work haskell did and continues to do.
All that said, I'm pretty sure Haskell is seeing little adoption because of the learning curve.
> The most successful languages let you be pure-functional where it makes sense and then stateful where it makes sense. Haskell doesn't, really (from my cursory reading about it).
Haskell almost certainly does this, this is actually one of the best features of haskell -- it lets you do functional things and stateful things separately and encourages you to keep them separate.
It's less that you specifically want an int/int case and more that you want consistent behaviour in a generic context - you might have some logic in a template that uses variant<int, T> and treats the int case specially (e.g. the int is an error code), but then you get a nasty surprise when it gets used in a case where T=int.
A common example is validation/result types, which often look like string (error message) or valid result. So e.g. you might have a username validator that returns Result<String, String> and then various other user creation validation things that return e.g. Result<String, EmailAddress> and in the end you compose them all together to get Result<String, User>. That's a very powerful style that has the advantages of exceptions (the "happy path" through the code is obvious and not obscured by all the failure handling) without their disadvantages ("magic" control flow, seemingly trivial refactors changing the behaviour). But it's less practical if you can't have Result<String, String> at the base level.
Yes definitely, I meant ADTs and GADTS -- Algebraic Data Types
They're a super good idea, so I'm glad that other languages are adopting it, but this is the kind of thing that haskell has had for a long time and is just second nature.
- non-nullable types
- immutability as a default
- typeclassses + structs
- abstract data types
- errors-as-values
- monads
Haskell or any other ML language didn't come up with all these things of course, but Haskell is one of the best languages
Take a look at rust -- it's basically got a near haskell-grade type system (and there are lots of ML languages with more flexible type systems than Haskell as well), with C++ like performance. It would have been a lot harder for rust's designers to incorporate such a nice type system without the exploratory work haskell did and continues to do.
All that said, I'm pretty sure Haskell is seeing little adoption because of the learning curve.
> The most successful languages let you be pure-functional where it makes sense and then stateful where it makes sense. Haskell doesn't, really (from my cursory reading about it).
Haskell almost certainly does this, this is actually one of the best features of haskell -- it lets you do functional things and stateful things separately and encourages you to keep them separate.