Haskell looks very interesting but I can't help but ask 'why do I need it?'. Currently I am learning Java since I want to get a jr.developer job later on and Ruby for some scripting and personal projects(maybe even Rails later). So Java is used in industry, Ruby is used in web and metasploit/ronin (something that I like to mess with), but what about Haskell? I am genuinely curious what Haskell can offer. I always see it mentioned on Reddit but I have yet to come across any notable project written with it. Could somebody with experience give me some reasons for me to learn it?
You don't need it. If you are a Junior developer (or aiming at being one) Haskell is a language you most definitely don't need.
Now, once you have your feet wet, it's worth learning. Here's why:
- Pure(mostly) functional language. This is in opposition to Java & Ruby, which while having functional aspects are OO (Object Oriented).
- It's okay not to know what a functional language is. It's making functions first-class citizens, such that a function becomes a value like any other.
- Separates IO from computation. IO is inherently impure and unreliable, so functions are generally pure and instead wrap IO in containers. Obviously, programs would be less useful (still use in the compiler running!) without IO.
- All of these concepts (and more) will change how you think about programming and make you a better programmer in all languages.
Haskell can be found in some backend stacks, the more notable examples I can think of are Mailrank (acquihired by Facebook) and Bump.
Personally, I've only done a limited number of projects with Haskell (a Postgres-backed beer API & IRC bot) but I've grown to respect it as a language and through limited exposure has made me love FP.
Functional programming is really more than first-class functions. A lot of languages have support for first-class functions (including Ruby's procs) that are not really functional languages. Functional (like all paradigms) is a bit nebulous, but to really be a functional language I would expect to see immutability as a default assumption, and I would expect to see only expressions, no statements. That latter expectation is really what gives functional programming its distinctive style. When everything returns a value, chaining together functions as transformations on data simply becomes the natural way to program.
To amplify what another has said, the emphasis of functional programming is side-effect-free code, where the default assumption is that functions don't have side effects, and so can be treated as components in a pipeline that modifies data step-by-step from its initial input state to its final output state.
Ideally, these components are composable and reusable, both to facilitate reasoning about the code and code reuse. The Haskell Standard Prelude is a fantastic example of this working out well.
Basically, it's based on the idea that the functions which are easiest to reason about are those with one well-defined input and one well-defined output which is completely determined by that input. You can't always have this, but functional languages attempt to get you as close as possible. The simplicity of pipeline-style programming is one of the happy little dividends of this kind of thinking.
From the perspective of "learn other languages to broaden your horizons":
Haskell is worth learning because it has an expressive, strong, static type system. Most other languages do not have that property (Java's type system is static, give or take null, and strong, but not expressive, and Ruby's is strong but neither expressive nor static). The Haskell type system lets you have conversations with the compiler about what your program should do.
You can declare a state type, and have the compiler tell you if you switch on the state and forget to handle one of the possible states (or if you add a state later and forget to update all the switches).
You can tell the compiler "I think this function is a generally useful utility function that I plan to extract out of this project and use elsewhere", and it will tell you whether there's some dependency on your project that you missed.
You can specify in a function's type "this function should have access to the database"; then the compiler can tell you if you're trying to access the database somewhere you didn't expect to. (A colleague has just spent a person-year of effort refactoring a Django web app, because all the database calls were happening in the view code, and they needed to abstract them out to scale.)
Of course there are ways to do some of those things in other languages, and of course there are also downsides to the static type system. But those sorts of abilities open up new programming techniques (even in languages with poorer type systems), and have shown me ways programming can be better.
>I've heard of a language being called expressive, but not a type system.
Haskell's type system is practically a language itself. It has many powerful features that aid with expression:
* sum, product and generalized algebraic data types (GADTs)
* higher-kinded types
* universally & existentially quantified types
* scoped type variables
* impredicative types
* associated types
* type families
* kind polymorphism (a new feature)
* type holes (also new)
>By the way, does Haskell's type system have the "value restriction" that you run into in ML?
I'm not sure what you mean by "value restriction". Haskell, like ML, is not a dependently typed programming language. For that you'll want to use something like Agda. As for why you'd want a language to not have dependent types? Well, having them introduces all kinds of considerations with regards to decidability and type inference.
The value restriction is a rule that governs when type inference is allowed to polymorphically generalize a value declaration. In short, the value restriction says that generalization can only occur if the right-hand side of an expression is syntactically a value. [...] The value restriction prevents a ref cell (or an array) from holding values of different types, which would allow a value of one type to be cast to another and hence would break type safety
It can be annoying to work around this, because there are potentially ML programs that would be type-safe and would otherwise compile if they were not hindered by the value restriction.
I got my answer, though:
Ii is interesting that in ML, the presence of mutable ref cells and parametric polymorphism requires the whole language to be dominated by a "value restriction"  to ensure that the type system remains sound, whereas in Haskell, because IORef's can only be created (and used) in
the IO monad, no such restriction is necessary.
There are two very different types of arguments typically made as to why to learn the more esoteric languages (Haskell, Lisp, Forth, others).
The first is the more common: learning these languages exposes you to other ways of programming, which in turn makes you a better programmer no matter what language you're programming in. This is unquestionably true. Mainstream languages are constantly learning new things from these languages, which means you will be able to apply the techniques you learn from them to your code no matter what language you write in. I have the misfortune of writing a lot of PHP at my day job, but it turns out even PHP has support for filter and map over arrays. If I hadn't learned functional programming, I would never have even looked for them.
The other argument, which is made less often, is that you can actually write great software in these languages. This argument is made less often because we can obviously look at the market and the TIOBE index and see that Haskell is way down at #30 with 0.323% of the market share. However, there are really great programs made in Haskell (xmonad, for one). There are also tons of great programs made in Lisps, especially Clojure of late. So, this second argument is not entirely a dead end either.
Revisiting something I mentioned in the first argument for a moment though, I would actually make a third argument that I rarely see. As I said, other languages are constantly learning new things from these languages. Haskell's community is full of PhDs studying at the intersection of programming and mathematics, and they are discovering the things that will revolutionize programming in the future. Haskell, for example, has been exploring strong static typing with algebraic datatypes, Hindley-Milner type inference, and typeclasses to support higher-kinded polymorphism. Those concepts are turning out to be incredibly powerful, and you will inevitably see them in other programming languages in the future. We've seen this before with Lisp (garbage collection, recursion, first-class functions), and there's no reason not to expect the trend to continue.
So, why learn Haskell? It's the easiest way to see what tools you'll have available to you in industry 20 years from now when the other languages catch up.
Which is a fantastic book, clearly written as a labor of love.
Erlang doesn't have Haskell's type system and doesn't seem to be of much interest for CS research types, but it's awesome for developing certain kinds of system.
I am curious about Haskell myself, and don't tend to need a lot of excuses to learn a language, but I don't perceive a "sweet spot" for it just yet, as in "I could go build X, and Haskell would be a great fit for it". Given how many smart people use it, I'm sure there are a lot of applications for it, but I also get a feeling that there's not one thing that really stands out.
One thing that I love to do in Haskell, and which Haskell is especially suited to, is writing interpreters and parsers. The other week I wrote a brainfuck interpreter (https://github.com/imeckler/skellfuck) in a couple of hours. Parsec, along with monads and functors, make this kind of thing a real joy to write.
It's a tiny detail but learning some functional ways of thinking gives you great alternatives to for/foreach loops when dealing with large lists/arrays/hashtables of data, even in other languages like Ruby or Java.
For the same reasons you need any programming language—to write useful software in!
> Currently I am learning Java…and Ruby
These are both good ideas. Java is widely used, reliable, and well tested for developing large applications. Ruby is simply a lot of fun to use, and one of the things you’ll discover while using Ruby is that it places a lot of functional programming idioms in an object-oriented context.
The issue with many popular languages is that they fall into much the same paradigm, namely imperative and either procedural or object-oriented, with some functional features borrowed for working with lists. It’s worthwhile to see that not all languages are like this, and learning a new language is not just about new syntax and APIs.
> but what about Haskell? I am genuinely curious what Haskell can offer.
Haskell will teach you to think about structuring your program in terms of simple data and transformations on that data. Object-oriented programming is about coupling data with behaviour, whereas a big part of learning Haskell is learning how to recognise high-level patterns in data structures and functions separately. In doing so, you can avoid the work of reimplementing common operations yourself.
You begin to say, oh, this is a data structure I can map a function over; I’d better make it an instance of Functor. And hey, I could use this data structure to represent this kind of computation, maybe it should be an Applicative and a Monad so I get some nice syntax for dealing with it. This function has a type signature that looks an awful lot like that other type signature—I wonder if I could implement one in terms of the other? And so on.
The type system and succinct syntax also make it very easy to create new data types, and you learn how this can help avoid bugs—don’t use a Boolean here, use an enumeration with two values; then you can’t mess up. Java discourages this by requiring more syntactic effort to create a new datatype.
A useful and oft-cited example of this is in the context of web frameworks: if you have separate data types for strings and HTML, that one simple thing eliminates a whole class of injection attacks. If you represent your links in the type system, then you can statically ensure that your site does not have any broken links. Simply put, quite a lot of bad things can be caught at compile time if you have a type system expressive enough to talk about them.
> I have yet to come across any notable project written with it.
There are more notable projects out there, but here’s my self-promotion. At my old job I maintained a compiler for ActionScript 3 in Haskell, as well as a build system that coordinated the compiler and other build tools to convert Flash games to iOS and Android applications.
Haskell is excellent at manipulating data structures—if that sounds ridiculously general, that’s because it is. The compiler is very nearly feature complete and, even with a certain amount of technical debt, was an order of magnitude smaller and easier to refactor than it would have been in an imperative language.
So there you go. From a recovering professional Haskeller, why you should learn Haskell. And, for that matter, the answer to “should I learn this language?” is always “yes”; but some languages should be higher on your list than others. ;)
Haskell can offer absolutely nothing Java can offer, while Haskell can't offer even 0.001% of what Java offers.
You see, there's a very, very good reason why you won't see any (even remotely) serious and useful software made in Haskell and why you won't see it used by companies (which means that jobs are literally extremely close to zero)
Haskell is nothing more than an exercise of constructing a language based on certain mathematical concepts, mainly abstract stuff like category theory.
As a result it as cryptic, hard to understand and useless in practice as those theoretical concepts (though the theoretical stuff might serve as basis for some other stuff that might be useful - not so with functional languages and especially Haskell)