Why Haskell Is Important
tweag.io
tweag.io
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.
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'.
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.
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/...
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.
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.
- 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?
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...
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.
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.
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.
I haven't been able to get exposure to a language that is comparable in abstraction power with Haskell, except for DSLs.
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.
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.
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.
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!
And don't forget HalVM.
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.
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.
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.
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 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.
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.
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?
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.
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.
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.
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.
Still my fellow academics will try to push in the direction they see fit.
Some of these ideas eventually find their way to other programming languages. Other ideas remain just ideas and academic experiments.
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.
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.
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.
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'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.
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.
Modern C++ has sum-types and 'optional' types.
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.
[1] https://en.wikipedia.org/wiki/Currying
[2] https://stackoverflow.com/questions/11218905/is-it-possible-...
Under active development, still WIP