Hacker News new | past | comments | ask | show | jobs | submit login
Why Haskell Is Important (tweag.io)
119 points by lelf 39 days ago | hide | past | web | favorite | 74 comments

> Haskell’s core principles, like purity and isolation of side-effects, [are] understood and appreciated by more today than ever before

If I were to summarize what I think are the most important ideas in the modern functional programming world, I would start with purity and isolation of side-effects (and the mechanisms that have arisen to manage side-effects). However, it seems like most discussion about functional programming centers on type systems and most of what gets imported to other languages is just fancy ways to do iteration. Purity and side-effect isolation, it seems, is seen as a weird curiosity that must be broken in order to write Real Software (TM). It feels like I've slowly watched functional programming get lost in translation the same way object oriented programming was.

I'm sure the past decade or two of hype around FP has done some good to real code bases by exposing new ideas to developers who might never have seen them before, but I worry that in another ten years, I'll open up someone's code and find a nested callback hell where state mutations are impossible to track.

The nice thing of functional languages is the establishment of invariants. A large part of that lies in purity / isolated side-effects. However, much of it comes from the type system.

When ported to 'imperative' languages, those factors from the type system help establish invariant given that people don't use all the footguns. Whilst it is sad there are still footguns that can ruin your invariants, getting better types helps you move away from the footguns. Moreover, it is much harder to export purity to different languages than it is to export good type systems.

And really, the good thing that is being taken over is 'make it easier to reason about correctness through invariants'.

Functional languages don't establish invariants, invariants is an abstract math concept and math way of thinking. Side-effects, on the other hand, have an important place in programming and CS.

If you can't make hordes of side-effects sit up and beg, in a large, complicated program, you can't call yourself a computer scientist or developer.

The functional notation really helps to establish a variant. In fact, most proofs of correctness for imperative programs essentially consider e.g. the body of a for loop to be a function.

I agree with you, but the point of the type systems is that they allow you to keep your purity while still giving the flexibility. A powerful type system is closer to a very powerful linter.

Example: it is fine to have internal state in pure functions, as long as that state doesn't break purity. Haskell's State Monad helps you ensure that. If you're doing FP in a multi-paradigm language, however, it's easy to make a mutation hell.


I think the problem with FP and OOP are never with the core concepts themselves, but rather the implementations in the form of multiparadigm languages. They make the escape hatches are too convenient and bad engineering is too accessible.

> Purity and side-effect isolation

This can be solved in many ways [1][2] and I don't think haskell's approach is the one that can be imported.

[1]: https://www.microsoft.com/en-us/research/wp-content/uploads/...

[2]: https://en.wikipedia.org/wiki/Uniqueness_type

It took me a while to understand why types are so important coming from stateful programming languages but it's surprisingly simple. In a stateful language types are limited to expressions and statements are not typed. In a pure functional language, where there are no statements other than declarations, the whole program has an inherent type.

In a stateful language a complex type system will eliminate errors in some expressions e.g. "Oh, you tried to add a float number to a file handle!". In a pure functional case a complex type system will eliminate composition errors in the whole program e.g. "Oh, you tried to throw an exception in the code which does not expect any exceptions!".

Naturally, type systems capable of typing a whole program tend to be more complex than ones only needed to type a single expression.

I think many of these comments are asking too much of a single short article. Or they want the article to be addressing the questions that they have rather than the question it was written to address. The author is stating very high level reasons about why Haskell is a fairly unique language, as a (relatively) practical, popular, and pragmatic vehicle of programming language progress (mind your ps).

For those that want concrete reasons for why it would be useful for a beginner, my personal honest opinion is that it may not necessarily be. Haskell does seem to require a decent amount of investment before it becomes practical. You may derive benefit from seeing the functional style in an enforced context. I know it informed and changed my python style a quite bit. You may find that these patterns were all around you the entire time and you didn't notice it, like learning new vocabulary words.

Anecdotally, my interest in Haskell seems to have been very good for my career so far and I have not had difficulty finding jobs that coincide with my interest in typed functional programming generally. Perhaps I have been very lucky.

Unbalanced post because it doesn't address evidence against Haskell. For example:

- Performance is lower than most systems programming languages.

- Performance is also more difficult to reason about.

- If Haskell is aimed at building large and complex systems, then where is the evidence, e.g. an operating system? (A compiler is just a pipeline so doesn't count; it is of a different kind of complexity)

- The GHC compiler internals are badly documented (despite some great books about its global architecture). Why do people who pursue clean software engineering methods not follow good software engineering practices?

I’m a bit conflicted about your point here, because they seem cherry-picked to highlight disparate aspects of Haskell that don’t make it less interesting or important.

Haskell is more often than not sued as a general purpose language, not as a systems language. Its performance is actually outstanding, usually equal to Java and often close to C. This means that Haskell can be safely used in any domain were java would be fast enough.

I find also somewhat arrogant to claim that there are no complex systems built in it. Just take a look at the webpage publishing this article. They mention several projects of great complexity. Here’s an example: https://www.tweag.io/posts/2017-03-13-linear-types.html

They are using Haskell as a prototyping language that lets the refactor and radically change the direction of their solutions at a low development cost. Haskell clearly is helping solve complexity here.

Also, where did the claim that GHC is badly documented come from, and how is it relevant to Haskell being important?

Just looking at randomly selected file in the repo, it looks actually quite well documented: https://gitlab.haskell.org/ghc/ghc/blob/master/compiler/simp...

> they seem cherry-picked to highlight disparate aspects of Haskell

I only said that the article was unbalanced and provided some counter examples. I didn't say that Haskell does not have many good uses.

I feel you're unfairly comparing Haskell to the likes of C/C++ that it's not really a rival with. Haskell is a (very) high level language, not a procedural language to build systems on.

A more appropriate comparison would be with commonly used high level languages such as Java and Python. The comparison here is meaningful because you'd build similar software with them as you would with Haskell.

There is no such language as C/C++.

Well-written programs in C++ are very different from programs in good C. (Bad programs are all alike.) C++ programs may be easily as "high level" as Haskell ones, higher than is possible in Java. C++ is clearly the language to beat, as no mainstream production language rivals its performance or expressiveness.

Forgive my ignorance, but how can C++ programs be easily as high level as Haskell, which is declarative, garbage collected and curried by default? Does C++ even have algebraic data types, not to mention more advanced stuff like GADTs etc. that are incorporated in Haskell?

I haven't been able to get exposure to a language that is comparable in abstraction power with Haskell, except for DSLs.

"Declarative" is a means to an end. Imperative gets you there at the same rate. Garbage collection compensates for inadequate resource management facilities. Currying is a neat trick that is fun when you find a way to make it do something useful.

Algebraic data types and GADTs are clever ideas very far removed from most real problems faced by real programmers, who have problems no language helps much with, and where the best we, as language designers, can do is try to keep the hell out of the way.

C++ has lots of such stuff too, mostly in template land. They can be useful to maximize the generality of libraries -- sometimes enabling great libraries -- but for most programmers most of the time they are at best a distraction, and more typically generate mysteries that absorb unbounded time.

Mark Dominus has some of the most insightful writing on the experience of coding Haskell.

> Algebraic data types ... are clever ideas very far removed from most real problems faced by real programmers

Everything else you've said has a case that can be made for it but algebraic data types being removed from real problems is utterly false. The contortions that Python programmers (myself being one of them) have to go through in the absence of ADTs are mind boggling. There's no language without sum types that wouldn't be significantly improved by their addition.

All variables are sum types in Python.

In Haskell as in C++, they serve as an escape valve where the formal type system is too constraining. In C++, we see std::optional, std::variant, and boost::result, and don't find we need many more.

Product types are ad-hoc structs, analogous to lambdas as ad-hoc functions. They are important to enable compounding of libraries from different sources, aside from their frequent convenience. Compounding libraries is still hard for other reasons, and so not useful as often as might be hoped.

In Python you have the opposite problem of C++ and Haskell: everything could be anything, and you would like them to be guaranteed to be only one or a few things.

Naturally by "sum types" I mean "sum types plus the associated language-level conveniences that make them reasonable to work with". Perhaps case statements may be enough. Perhaps arbitrary lambdas are needed. Anyway, they're not reasonable to work with in Python. I'm not particularly familiar with C++ but I doubt they're reasonable to work with in that language either.

C++ will probably be getting an equivalent of match statements in a near-future Standard. ("Near" means "before civilization collapses".)

I think declarative is a paradigm, a way of thinking and reasoning about code, rather than a means to an end. Declarative code would obviously raise the abstraction level (as it hides implementation details that you produce with imperative code). I don't see how imperative code would hold an equal abstraction power.

As for ADTs and the like, these are very basic features used all over Haskell code, combined with pattern matching. There are much more advanced abstraction concepts that are used all over Haskell libraries.

I'm sure C++ has good facilities for abstraction. However, as it lacks many of the very advanced abstractions that Haskell has, I find it far fetched that C++ could be described as an equally high level language as the likes of Haskell. From what I understand, that's not even the intention of C++ to begin with.

Btw thanks for that reference to Mark Dominus, seems like interesting stuff!

“Real programmers don’t use x” - said by every proud programmer that don’t want to learn new concepts since the beginning of time.

Real C++ programmers use the hell out of features added because of demonstrated industrial need. Many of them were copied from ML, others Haskell entirely lacks. Haskell has some features C++ doesn't need, that would just make programs harder to understand without actually making the language more powerful.

Would be helpful if you gave some examples!

Unfortunately, without concrete examples it's hard to grasp what features you really mean.

Unbalanced comment because it doesn't address the good points of the article. Yawn.

Probably not relevant, OS written in Haskell does exists, though: https://en.wikipedia.org/wiki/House_(operating_system)

And don't forget HalVM.

It seems like the condensed version is "The idea of Haskell is more important than the language itself", which doesn't really sound like a convincing argument to answer why the language is important.

There was a hackernews post yesterday where the top voted comment asserted that computer science and maths is (in practice) only useful for data structures and algorithms; everything else needed either physics or social science. This is why Haskell is important. Haskell will help teach people the mathematics behind program construction: how to write composable code, how to reason about effects, how to write consistent, general, less ad-hoc APIs.

The balance between beauty/structure and effectiveness is tough to get right.

There are cases where functional programming is essential, and there are cases where it's an absolute overkill.

Developing the judgment to tell which is which is this 'experience' part. 25 years in this industry and I still undergo frequent regret when I write ugly-but-effective code, and frequent anxiety when I have to write 300 lines to accomplish what can be accomplished in half that.

Time-preference is a blessing and a curse.

But it doesn't seem to.

Products built in haskell don't seem to have dramatically lower maintenance costs. They don't tend to have features that other products don't have. Nobody buys math.

In all of the recruiter spam I get, the only time that recruiters lead with "what language we use" rather than "what we are building" is when the company is using haskell. This seems backwards and gives a poor impression.

There might be 100 POPL papers that I can use with haskell extensions but ultimately the act of coding is nowhere near the top of the list of important things when building systems to solve problems.

> Products built in haskell don't seem to have dramatically lower maintenance costs. They don't tend to have features that other products don't have.

That is your anecdote, mine is the opposite. Using Haskell at my place of work we have lower maintenance costs than other competitors that use Python. We also have features they don't have, such as checked purity (a guarantee that a financial calculation is reproducible) and transparent batching/caching/provenance (made possible by Haskell's expressiveness). None of this would be possible in Python or Java.

Language/notation, is IMHO critical for the ability to think using the right abstractions. To take your argument to the extreme, we should all be still using machine code, because tools don't matter.

This doesn't seem correct. The author specifically says that Haskell is important because it is used in industry.

There's a lot to be said for a language that is a) important as an idea and b) gets used enough to test out those ideas in practice.

I'd agree with the author that Haskell occupies something of a sweet spot in that regard.

It is an interesting idea. That does mean that Haskell should never get too popular, if it gets popular it won't work very well for testing new ideas any more.

Sounds like we should avoid success at all costs.

In our startup due to earlier experience working with pandoc, we tried to give Haskell a try.

It was very difficult for team to pick up and then they took longer to accomplish very little. It did drain out confidence and make us think, we are not so clever.

So later moved to Python, and suddenly things changed. In the meantime on personal level at present learning lisp. Once finish will try to work on Haskell again.

I think Haskell along with lisp will be good on learning functional programming for my team. It will help them solve logical problems using functional paradigm as well. So in future they can pick up procedural or functional paradigm to solve logical problems better suited to problem at hand.

There is unfortunately a large learning curve for production Haskell. It's a very different language to most imperative object-oriented ones, that are all broadly very similar. However, the concepts that folks will learn (Monads, Monoids, Functors, Profunctors etc etc) are taken from math and will likely be around for another 100 years. This is not disposable knowledge, and for me at least, it made a refreshing change from learning ad-hoc concepts from each successive OO fad framework I had to deal with.

I have been learning Haskell from these two books over the last 4 months: "Practical Haskell by Alejandro Serrano" and "Practical Web Development with Haskell" by Ecky Putrady. With other languages I usually just skim through a book figuring out how the basic data structures, flow control and operations then start writing a toy CLI app or server but with haskell I felt completely lost when trying to follow examples in library documentation, even after several weeks of reading books. So I found it's really worth carefully going through the programming book and doing the exercises, at least beyond the monad transformers section, before diving into real code. I'm over the hump and am writing & understanding working code now, but still a long way from the level of mastery I have with imperative programming.

I think the problem with Haskell are not the concepts per se, but rather the terrible ergonomics (too many cryptic operators, point-free syntax, language extensions) and TERRIBLE learning material.

Monads, for instance, are hard to invent but are easier to use than most libraries. Most people won't come up with Monads and will only consume them. But books and Monad tutorials focus instead on explaining what they are and how they were invented. This is unnecessary.

Another problem is that the coolest things (monads, lenses, syntax extensions) are bolt-on, rather than built-in. So we compromise syntax (and sometimes consistency) in the name of extensibility. Such fundamental things should be in the StdLib. This is the same problem Javascript suffers from.

I strongly believe that a new language with the same semantics but a more approachable syntax and better learning materials (like Python) would be way more successful. Maybe that's OCaml but I'm not too experienced in it.

Syntax-wise Ocaml is waaaay weirder than Haskell. In fact, Haskell is a pretty typical representative of the whole ML language family, with StandardML being the cleanest of them all.

Actually, OCaml is much closer to the original ML that SML.

> It did drain out confidence and make us think, we are not so clever.

I don't want to sound arrogant, but maybe that is the truth right here? Maybe what you struggled with was not what you should have actually done the way you did?

I see everyday that "quick" solutions in Python are woefully incomplete and tend to just ignore the complicated corner cases. You don't get away with that in Haskell in my experience. So maybe you just underestimated your problem domain?

I understand that the ecosystem of Haskell is much smaller than for instance python, but an experienced programmer should recognize that. So if your team struggled it could indicate that your initial specification was just too shallow?

No you don't sound arrogant, our team is still learning. You are right we shouldn't have approached the way we did due to inexperience.

My team only did C, C++ and bit of Java in University and majority of the things they learned were more object oriented and procedural programming.

As none of them were trained in haskell, it took them a while to get to do anything. Moreover we were just working on web application bakcend, so they felt instantly productive in Python. We were not cracking compiler or some hard computer science problem, we were just doing run of the mill web application like Amazon marketplace.

So I said may be in future may try Haskell. Right now on a personal level trying lisp.

> No you don't sound arrogant, our team is still learning. ... So I said may be in future may try Haskell.

I'm conflicted as to whether functional programming like Haskell a right business solution to real-world problems. Businesses need to hire developers, and almost all of them taught procedural programming in school.

Is functional programming innately more intellectual / hard to grasp than procedural programming? Or is it just not taught enough in school? I'm not really sure.

Procedural programming more closely matches the real world with one thing happening after the next. Functional programming more closely matches math with one thing represented as a transformation of another. To me, one does not seem any more difficult than another, but clearly, many more devs understand procedural programming better than functional.

In a real-world business, you need to hire developers with the skills they have. Junior devs are far more comfortable in procedural programming than functional programming. Most businesses can't afford a team of senior devs. So regardless of whether one is easier/harder/better/etc., we get procedural programming, not functional.

It's worth bearing in mind that when writing something side effecting (reading and writing to a database for example) in Haskell, it will be done imperatively.

There's definitely a bias towards the familiar however, it took me a while to get my head around the "FP way" as it were. The frustrating thing is that like you say most people are just trained in procedural programming with often at most minimal contact with anything functional which causes a kind of pressure on the whole industry.

Sure, if you never had any exposure to Haskell, you should probably not start your business with it ;). I wonder though, did the team know what to do and struggled only with the how or did they also struggle with the what and shadowed this problem by doing something (a.k.a. "agile development" ;) )

“Why Haskell is important” according to a Haskell consulting company. So taking this article with a big grain of salt.

Haskell might be a great language but barely anyone (besides CS academics) uses it.

We use java and python in production because (among many other things) they’re very popular.

Popular languages have large archives of open source packages and easy to find communities that save enormous amounts of headaches and time. The opposite is true of Haskell, at least for now.

I am still not clear on why Python has become popular. It wasn't a few years ago. They might use it more in universities nowadays but it seems backwards if the business's starts using languages just because they are used in education.

By the way, I don't here much about companies using Python in Scandinavia except for some AI.

All valid points. It could in the future be done in a better way is not really interesting when you are working with your boss breathing down your neck.

Still my fellow academics will try to push in the direction they see fit.

The most important thing about Haskell is this: serving as a test bed for programming language theory and ideas.

Some of these ideas eventually find their way to other programming languages. Other ideas remain just ideas and academic experiments.

I don’t know about that, Haskell has been a stable language for a while now...

Google "haskell motto"

I don't doubt that Haskell is a great language, but in my experience, if you have to publicly anounce to people at length why a thing is x, it isn't x.

Not true at all. We live in a world were marketing determines the standards used. The current trend is actually to give programmers less guidance on writing correct, composable code ("Dynamic" scripting languages).

I think that was true 6 or 7 years ago, but we’re heading completely to the other side. Typescript over javascript, rust over c, swift over objective-c, dart adding improved support for static typing, go thinking about generics, etc. I think everybody now go toward compilers or PL enforcing more ( and as soon as possible) rather than give the programmers more dynamic features.

In my humble experience it can be either. Case in point - the adoption of disinfecting of tools and hands before surgery in 189x-s.

That depends on what your definition of “is” is. When something “is” X only if the mainstream understands it without explanation, then you may be right.

Yes, and it is also important to understand what “is not” is not.

I'm mainly a C/C++ programmer, I use also python, I'm learning Go and I'm reading about Rust. But I think my programming skill are a little "stereotyped", so I'm looking for something different, you know, to open my mind. So I read the article, here on HN, about all the "exotic" languages, Lisp for example and others. I was reading this article about Haskell and I think it's too abstract to stimulate a novice to go further. Some details about the advantages cited and related examples should be present to give motivation to the newcomers. On the contrary, the part about the evolution gave the impression of an immature language. My two cents.

Question is, why would you want to consider the more "exotic" languages? What would the motivation be, for you, in trying out new languages?

The hint that these might not be for you, yet, is right there in your question. You consider yourself a C/C++ programmer. I think most of the folks who grok these Lisp and Haskell languages just consider themselves programmers plain and simple, or engineers, or curious little heads, or artists, or something similar.

I would consider other programming languages different from c/c++ because I don't want my capability to solve problems bonded to specific tools, this is the motivation I learnt other languages.

Evolution maybe, the animal becoming too specialized, in case of environmental changes, will face the extinction.

I'm looking for tools better able to solve specific problems. You can stick screws with an hammer, maybe it's faster but a screwdriver tool exists to better solve the problem and its evolution the electric screwdriver is the state-of-the art and probably the best choice. Now, having to deal with a limited resource, time, I have to choice what to learn seriously and this article doesn't help me to do a choice. Those choices also could influence my professional capabilities in the futures, because, you know, I do the programmer to live.

> just consider themselves programmers plain and simple

Plain and simple programmer is bullshit, IMHO. What do you write in your CV, "professional programmer plain and simple" :-) ? Oh, please, save your rhetoric.

You don't go lisping to make your CV look pretty. That doesn't help at all. On the contrary, it might be even damaging, as some discussions here on HN have shown in the past.

If you're "looking for tools better able to solve specific problems", your best bet right now might be Python. It ain't pretty, but the momentum behind it is tremendous. Tons of libraries, books, how-to's and developers out there willing to help. From a practical point of view, you couldn't ask for more.

> You don't go lisping to make your CV look pretty.

Look, I didn't write that. This is your affirmation. As I wrote, and I repeat, I think that being specialized to procedural/object languages, for some kind of problems that could be a limit. So I'm looking for different paradigms to change the way I approach problems. Now I have a limited time, how I should spend it ? Now, because I'm a professional programmer I would like something I can use and improve my CV. So what?

> your best bet right now might be Python

Again, its paradigm is a stereotype of other language I know.

What's your problem ? Are you the author of the article ? Look, I think that the point of that article is "study Haskell, trust me", so it isn't an help for newcomers. I only express my opinion. The title is "Why Haskell is important" and I think it fails to explain the more important point that is "why". So, why ? Moreover, why Haskell and not F# or Erlang, for example ?

I don't think you're wrong in reasoning that you would learn new beneficial concepts by picking up new less mainstream languages that pioneer these concepts.

I've invested some time in picking up Haskell and it's been worthwhile personally. When you know C, Java/(some OOP lang) and Haskell, everything else sort of falls in between. Ultimately makes your journey easier as a developer.

> looking for something different..to open my mind

I started reading a book recently, I thought you might enjoy:

Programming Language Explorations


It takes about a dozen languages and highlights various concepts. A kind of light, easy reading, but it did open my mind to some new strategies/approaches.

I think that when mentioning the effect of Haskell on other languages, things beyond rust deserve to be pointed out.

Modern C++ has sum-types and 'optional' types.

Python has lazy evaluation (generators).

Java-script really likes higher order functions (reduce, map, etc).

> Python has lazy evaluation (generators). > Java-script really likes higher order functions (reduce, map, etc).

It is a hard sell to claim that either of these were invented or even popularized by Haskell. Just because something has functional roots, doesn't mean Haskell is related to the success of the feature - there are plenty of older languages (LISP!) that have the same features and that likely has way bigger influencing effect.

In fairness, the list comprehension syntax in python was taken directly from Haskell: https://wiki.python.org/moin/PythonVsHaskell

I’d love to see a Haskell in Lisp’s clothing. (The Haskell that exists has so little syntax that source code often looks like a mass of unstructured text.)

Haskell, being a curried [1] language, seems fundamentally incompatible with Lisp, which has variable arity [2].

[1] https://en.wikipedia.org/wiki/Currying

[2] https://stackoverflow.com/questions/11218905/is-it-possible-...

there's [Hackett](https://github.com/lexi-lambda/hackett) though it's more an implementation of haskell within racket

There was Liskell, but it seems it's dead.



Under active development, still WIP

Those very same arguments could be rather used to say why Racket is important.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact