4 ms·
Could you give an example of something that is simple to express in Haskell, but harder and error prone to express in Go/Rust/[other imperative languages]? Hone
by spekcular 5y ago
Could you give an example of something that is simple to express in Haskell, but harder and error prone to express in Go/Rust/[other imperative languages]? Honestly curious!
- the_af 5y agoJust about anything written in Java requires more boilerplate and rituals than the same function in Haskell. (Or used to, of course: Java has slowly evolved and adopted FP idioms too). 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.
- spekcular 5y agoRust isn't a bizarre comparison at all. Suppose I have before me some programming task. I can choose Rust, Haskell, or something else. Anyone arguing for Haskell in 2021 (2022?) has to justify why it's a better tool for the job than Rust.
- the_af 5y agoWhy? 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?
- spekcular 5y agoI'm saying that programming languages are tools for completing programming tasks. So, yes, when faced with a task I think about which one is best. 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?
- the_af 5y agoHow can you identify the problem if you first don't 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.
- spekcular 5y agoHow do I decide? I look at the features and documentation for each language, and try to figure out what problems it is best suited for. I also ask various people I trust (and HN commenters!). 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.
- youerbt 5y ago> Anyone arguing for Haskell in 2021 (2022?) has to justify why it's a better tool for the job than Rust. 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.
- w4rh4wk5 5y agoI'd say, take a look at error handling. In Haskell you can accomplish a lot by just using `Maybe` and `Either` along with the functions related to them, provided by the standard library. Haskell's pattern matching feature makes it even more straight forward to handle these types. 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 https://github.com/oktal/result/blob/master/result.h for example.
- jmfldn 5y ago"Could you give an example of something that is simple to express in Haskell, but harder and error prone to express in Go/Rust/[other imperative languages]? Honestly curious!" 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.
- whateveracct 5y agodata 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 :)
- juxtapose 5y ago> modulo bottom 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
- whateveracct 5y agoResplendent!