An example: you cannot express in Java "this function does not write to disk", its type system simply doesn't allow it. In order to make sure, you'd have to inspect the code of the function, and the libraries it uses. In Haskell, this is trivial because just by looking at the type of the function you can tell if it's even possible for it to do I/O.
Go requires tons of boilerplate and didn't have generics until recently; there's your answer.
Rust is a bizarre comparison. Haskell predates Rust and Rust takes some (many?) ideas from it or from languages within the same pedigree. Also, I don't know anyone who thinks Rust is "simple", so why ask about this comparison? Write Rust if you want to, no Haskeller is going to complain about your choice.
I'm not trying to be dense. Are you saying for every programming language you choose, you make an strict ordering of every existing language and then decide which one you'll pick?
Do you think there is a strict ordering of "is better than" between Haskell and Rust?
Examples:
Need to copy a bunch of files? Use bash.
Need to do a quick Monte Carlo simulation? Probably use Python since it allows me to write it the fastest (based on my familiarity).
Need to write drivers? Use C.
I don't think there is a strict ordering of "is better than" between Haskell and Rust. I think for many purposes they are roughly equivalent, and for some one or the other is more suited to the task.
But, if I can't identify any problem for which Haskell is a better tool than Rust, why would I ever learn Haskell?
How would you even decide you want to learn Rust and not Haskell if you didn't know either? Hype? Popularity? Because your coworkers know Rust, or the codebase is in Rust? Those are all good reasons, honestly! So if you were in a Haskell shop, you'd have reason to prefer Haskell over Rust. There's your answer. Either will be better than Python for a medium/large project, but likely worse for a really tiny script or program.
How did you pick Python over Ruby? They are very similar, yet they have many differences. Think about it, and there's another answer for you.
I agree: If the problem is "How do I get paid?" and the best available job requires learning Haskell, then learn Haskell!
But, I think this is kind of an evasive answer. First, not many jobs require Haskell, so if my choice of language is dictated by economic concerns I'm better off with, say, Python or various web dev stacks. Second, because I have in mind a situation in which the implementer has a fixed problem and is trying to figure out which language to use. (A personal project, say.) I'm sorry if this was not clear.
So, I ask again: are there any problems for which Haskell is a better solution than Rust?
edit: Regarding the Ruby question, I think the language has various flaws, but going into detail would take way too time. A shorter answer is: numpy, scipy, pytorch, numba.
Well, and what have you found so far in relation to Rust and Haskell? It seems to me you know what you have to do.
Let's assume your answer is "I read every introductory page in wiki.haskell.org, read and worked through a couple of tutorials, and I still cannot figure it out". If so, do you think a comment here in HN is going to convince you of picking language X over Y?
> So, I ask again: are there any problems for which Haskell is a better solution than Rust?
Realistically, which kind of answer do you expect? A summary of the "Why Haskell" and "Why Rust" pages? I'm sure they exist and you could take a look at them and decide.
Yes. Because I'm a highly fallible person and very open to the idea that a Haskell expert might be able to point out a good use case that I missed.
> Realistically, which kind of answer do you expect? A summary of the "Why Haskell" and "Why Rust" pages? I'm sure they exist and you could take a look at them and decide.
The selling point of Rust is (very, very) roughly "C++ without the bad parts, and some more good parts." Given the demonstrated utility of C++ (and demonstrated pitfalls) this is manifestly appealing. Avoiding memory safety related security holes alone is huge.
That's an example of the kind of answer I expect.
I'm not a Haskell expert, I just dabbled with it and liked it.
> The selling point of Rust is (very, very) roughly "C++ without the bad parts, and some more good parts." Given the demonstrated utility of C++ (and demonstrated pitfalls) this is manifestly appealing. Avoiding memory safety related security holes alone is huge.
The selling point of Haskell is that it's a Functional Programming first language (see: "Why Functional Programming Matters"), has a better statically type system than C/C++/Java which makes whole classes of bugs common in those languages harder to write in Haskell (so if writing correct code is a priority, that's your use case), and memory safety related security holes are harder to write, just like with Rust. Laziness (or non-strictness, whatever) is also a big if controversial selling point (why: read "Why Functional Programming Matters").
If you like slightly less opinionated (or non-strict by default) languages, you could go with OCaml or Standard ML instead.
Why would you prefer Rust? Why don't you ask a Rust advocate?
Haskell is good for writing general purpose code in the Functional Programming style [1]. It's not the only language that supports this style, but it's one of the most opinionated about keeping to this style that is also general-purpose, pragmatic, and has some industry adoption [2]. You can also see read what wiki.haskell.org has to say [3].
[1] "Why Functional Programming Matters": https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.p...
[2] Commercial Haskell: https://github.com/commercialhaskell/commercialhaskell#readm...
[3] "Why use Haskell": https://wiki.haskell.org/Introduction#Why_use_Haskell.3F
> If you're asking people to learn Haskell in order to find out which kinds of programs it's better on
I'm not asking people to do anything, but if they do want to understand the tradeoffs of any technology, sometimes the only way is the hard way: learning it. I find all too often what people really want to know is a quick and easy glance at how much language X differs from something they already know (usually C derivatives, or Java, or Javascript, or Python).
I don't think it's unreasonable to expect a more concrete reply to that quesiton than "First master the language, then figure it out."
Let me be honest here and say I don't find your tone helpful. "You still haven't told us" makes you sound as if you're in a group, critiquing from the tribune. This isn't helpful for honest conversations. There's no "us", there's just you, and I don't owe you any explanation.
That said, I provided plenty of links in my answer above, which address at least some of your questions. Have you read them? The site https://www.haskell.org has plenty of testimonials that you could also read to figure why some shops and people have chosen Haskell.
Maybe you could send Simon Peyton Jones an email, he's one of the friendliest guys in the software industry. I don't think I've ever read or heard him say anything dismissive about any other person or technology.
What I cannot do: provide you with a single sentence stating why you should use Haskell. I don't think anyone can. For the record, I found your single sentence about Rust totally unconvincing as well; I do find Rust compelling because of tutorials, long articles I read about it, and a workshop I once did with a Rust practitioner. None of this is equivalent to debating/convincing on HN.
(Similarly, I find Go not compelling because I had to use it for my day job and everything about it made me chafe).
So my advice to you: read the links I provided, and keep in mind they are just a starting point. Do a workshop. Work on a midsize problem, maybe also write some Advent of Code Haskell solutions.
Or not. It's ok to just go with your gut feeling and focus on Rust. There's a finite amount of time you have available for exploring technologies. Rust will serve you well.
The links you gave provide general information about Haskell, but do not answer that question, from what I can see. I don't want a single sentence reason, just a compelling one.
Again: I'm not doing this to be adversarial. A decent number of people seem to really love Haskell and extol its virtues. So I'm trying to carefully check that I'm not missing something.
Haskell is a general purpose language, so it's good for any domain well served by a general purpose language. The rest is the list of benefits of statically typed, lazy first, pure functional programming languages.
"Haskell or Rust?" is not a question that can be meaningfully and objectively answered in a comment on HN.
I've learned Haskell and used it for a relatively long time until I finally understood what is so nice about it. Again, very hard to explain, and a lot of that comes just from the combination of simple, functional language features. Like: how currying works together with function composition; how sum-types and product-types make it easy to model your domain / problem and using pattern matching to write code that is easy to understand and does the right thing; how a powerful type-system can be leveraged to rule certain bugs out almost completely, right from the design phase. Leveraging monads by using Haskell's special `do` syntax.
I only really understood this after having done imperative style programming, then having done functional style programming, and then trying to apply the functional style in an imperative environment and seeing why it does not work there (typically because of some missing language feature).
Edit: Just wanted to point out, I am not a fan of Haskell as a whole, since there are a lot of drawbacks in my opinion. There are valuable things to learn from the language, but I do think Rust is superior.
And the rest of the answer is, essentially, "beyond that, if you want to see, you're going to have to learn it". I also don't find that unreasonable - there's only so much you can explain to someone who doesn't know the language. And that's not just Haskell, that's any language. I kind of have an idea of what Rust is about, but if I want to really understand it, I'm going to have to learn it. Same with Haskell, or Lisp, or pretty much anything.
So I found the_af's answer to be quite helpful. And I'm the guy who asked the question, so...
You ask for a lot of reasons considering the amount you dare to provide. No, nobody has to do that, it doesn't make any sense. Let Rust people comment under articles about Haskell why Rust is the better choice.
A lot of this translates to Rust, as Haskell influenced the language design of Rust. In Rust you have `std::option::Option` and `std::result::Result` which relate closely to `Maybe` and `Either`, respectively. Also pattern matching is available in Rust.
When you then look at other (imperative) languages like Go, C, and C++, error handling becomes a bit more cumbersome IMHO. I am not talking about explicit or implicit error handling. It's more about urging the programming to check for and handle errors, and also giving them the necessary tools to do that efficiently.
In Go, you have lots of `if err != nil { return err }`, which is cumbersome to write (luckily we have snippets) and _clutters_ the code. Yes, it is explicit and easy to read, but I don't think error handling should make up 4/5 of the lines of your algorithm.
The same applies to C, more or less, as functions typically tell you about success or failure via their return value. Like `err` in Go.
In C++ we have `std::optional` which is handy, but C++ lacks a lot of functional features and convenient syntax to take full advantage of it. No straight forward pattern matching here. There is `std::variant` to create sum types, but I've only seen that in use occasionally. There is also `std::expected` on the horizon, which is similar to `Either` / `std::result::Result`, but adoption will take ages.
C++, being a complicated language, makes it very difficult to just come up with your own wrapper classes that _just work_. See https://github.com/oktal/result/blob/master/result.h for example.
This is hugely subjective but if I'm writing large data transformation pipelines for example, the type system and the compositionsal power of a language like Haskell, or pure FP scala, makes such a task an absolute breeze. It all just slots together like Lego. You have a high degree of confidence that the thing will work, and you can use local reasoning to understand the parts and, by extension the whole program, since the laws of composition and the lazy eval model make this trivial in comparison to imperative code. The way code can compose, the runtime and the resulting local reasoning, can honestly feel like a super power sometimes. Beware of thinking programs written in other languages are simpler to reason about, they might not be. There's more than the "simplicity" of the code to worry about in software.
Is it better than Rust? I can't answer that sort of question, but I can tell you that full-throttled pure FP can be a pretty damn amazing tool when you need it. Rust seems to be a fascinating language for doing, say, systems programming, with some FP-like idioms built in. Amazing! Comparing languages though is tricky, it's always about tradeoffs, context and so on. I don't believe in a hierarchy of languages.
data Void where
Void :: { absurd :: forall a. a } -> Void
^ I just defined a type with no inhabitants [1] along with the ability to use a value of it to prove anything. And it leans on the type system features & ergonomics Go & Rust don't even get close to having.This is a pedantic example in a way, but this type is actually very useful in practice! And defining the type almost reads like English (or at least math English.)
Haskell is just a different world. You program with type variables of different shapes and sizes and relationships like it's nothing and it Just Works. Go's new generics & Rust's are crufty in comparison. Both due to syntax and semantics.
[1] modulo bottom..I know, I know :)
Since GHC 9.2, with UnliftedDatatypes you can define real uninhabited types!
{-# LANGUAGE UnliftedDatatypes #-}
import GHC.Exts
data Void :: TYPE UnliftedRep where
Void :: { absurd :: forall a. a } -> Void"I'm running Ubuntu so I installed ghc and cabal-install, then installed stack (since people are recommending that) by running their script. Then I found out that haskell-platform is the blessed route (and contains stack) so I uninstalled ghc, cabal, stack and installed that instead. Stack was not installed along with haskell-platform (what? why? ugh... whatever), so I reinstalled it manually.
Great, now I have the tooling all set up! Slightly more irritating than other languages, but it's there.
Now to build my app; I want to give websockets a whirl so I grabbed the server example and stuck it in a newly created stack project (stack new foo worked well) as app/Main.lhs and re-pointed foo.cabal to look at the .lhs extension. Ok, next step is to build it, stack build - it complains that I don't have websockets installed, ok, stack install websockets - it whirrs away for a while downloading stuff and then finishes. That was easy. stack build - same error, still no websockets (???). I take a look through the stack.yml and foo.cabal files and can't find websockets mentioned anywhere (in NodeJS I'd have done npm install --save websockets and it would have both installed the lib local to the project and updated the packages.json file appropriately - same sort of thing with Python via pip + freeze). Presumably I missed the '--save' or equivalent, but I don't see anything like this in the stack install -h docs.
I hop onto irc for help, and am informed that you don't stack install project dependencies; that installs global packages (huh? I thought stack was supposed to help in keeping things local... whatever). Then I find that I have to edit the foo.cabal file manually to add my deps - seriously? Wow. Ok... So I do that (in the wrong place, then eventually in the right place) and finally my stack build works. Awesome! But also grrrr! Why are there two config files talking about libs and how am I supposed to know which one I'm meant to add stuff to?
As an aside there's also the expectation that I should figure out which versions of libs are snapshotted on stackage, but searching on the website funnels me through to hackage (via hoogle) and gives me no indication on the way as to what snapshots they have. I ended up finding the snapshot listings on stackage and using ctrl+f in the browser to figure that out - after checking my stack.yaml to work out what snapshot list I should be looking at. Seriously. These leaps are crazy :)"
I should point out this is from 5 years ago. Probably things are better now. But some things are not, e.g. installing Haskell on Arch Linux [1].
[0] https://www.reddit.com/r/haskell/comments/4sihcv/comment/d5a...
As I say though, I think things are moving in a better direction now (I haven't taken a look at Haskell for a while).
While I get not everyone has the same background, stack works very similarly to how C#, java, rust and just about every other compiled language with its own dependency management system works. His being surprised says more about him that it does stack.
Python, which you mentioned in your other comment, is super irritating re: tooling -- yet people seldom find the need to "justify" using it.
Sure, the simplest (and mostly wrong) way of setting Python up is seemingly trivial, just like Haskell's. You'll soon run into all kinds of trouble with pip and dependencies and environments and typechecking and linting and the myriad of confusing and slightly incompatible tools that form Python's wider ecosystem.
Today you would install 'ghcup', which manages compilers and build tools. Default installation includes the compiler (GHC) and build tool (cabal). Then you create a folder, run 'cabal init', add 'websockets' to your '.cabal' file ('build-depends'), and you're good to go (run 'cabal build/run'). I think it's pretty reasonable now, far better than other alternatives.