Is Haskell really the language of geniuses and academia?

Original author: Artyom Malyshev
  • Translation

I once had a discussion with a founder of an Israeli startup developing a GPU-based database with a focus on speed. The work stack included Haskell and C++, among others, and the founder was complaining about how hard it is to find competent programmers. Which was part of the reason he came to Moscow.

I carefully asked if they considered using something more popular and new. And even though the answer was rather polite and well-supported with arguments, it still sounded like “Come on, don’t even bring up these toys”.

Until then, all I heard about Haskell could be summarized as “be VERY careful in dealing with it”. To get to know Haskell programmers better, I came to a topical Telegram chat with some questions. I was quite afraid at first, and, as it turned out, I was right.

Haskell doesn’t lend itself to popular explanation, and people seemingly don’t even try. If the topic is ever brought up, it’s only talked about in full depth and as objectively as possible. Someone wrote to me: “One of the defining features of both Haskell itself and its community is that they didn’t try to achieve any kind of mainstream recognition. Instead, they focused on building a logical, principal way of solving real problems over trying to appease the widest audience possible”

Nevertheless, a couple of people did tell me about their experiences, which are shown below.

Denis Mirzoev (nolane): When I was in college, they’ve offered me to do a Coursera course on Haskell for extra credit. Then we also had a functional programming course that included Haskell. I’ve written one of my term papers, plus the graduation paper, on GHC. Then I found a job as a Haskell programmer.

It was, and still is, hard. When you start learning Haskell, you have to cram a lot of new concepts into your mind. It’s like learning to code from scratch all over again.

People tend to forget (or smooth out) their earlier memories: like when they were struggling to understand what a “pointer”, “function” or “class” was. Maybe that’s why it’s so hard for them to learn Haskell: it gets harder to learn new stuff with age.

Doctor_Ryner: Once I failed my trial period at a job because of a Redux fuckup, so I tried to get a bit more comfortable with it by watching videos from its creator. First I practiced in JavaScript, but then I learned about Haskell, considered to be the “true” functional language. I was fascinated by its unique concepts and how neat it was.

Tutorials aren’t too user-friendly, though, plus its imperative background prevents new concepts from emerging.

Yuri Syrovetskiy (cblp): the hardest thing is to learn Haskell as your second language, when memories from learning the first one are still fresh,

What is Haskell good and bad it?

Doctor_Ryner: It’s concise, elegant and flexible. No wonder half the libraries there are on EDSL (or at least it feels like it).

Yuri Syrovetskiy: It’s (subjectively) easy to adapt your thoughts to code, it has a great balance of imperative and functional paradigms. Building abstractions of data and algorithms is rather simple, which allows to think about the task at hand without getting distracted by little annoyances too much.

John Doe: Strict, strong (even fascist, I’d say) typization.

Igor Shevnin (interphx): A great type system. It’s not as powerful as in Idris or Agda, but still reaches that convenient middle point where you can describe almost anything, and yet type inference works well. You don’t have to mark them manually every time.

But a powerful type system forces you to pay closer attention to values transmitted. A bunch of type definitions could look like a boilerplate. Each command has its own extension set, or doesn’t have them at all. The code is “denser” — each string often carries more information than in other languages, so it’s harder to read for an inexperienced developer.

Doctor_Ryner: When learning Haskell, you’ll probably stumble upon this saying: “If it compiles, it’s probably correct”. Null doesn’t exist, the functional paradigm itself is very strict and keeps you within certain guidelines, which in most cases lead to better design.

For example, Haskell doesn’t have variables — only constants. You don’t have to keep track of what’s assigned where. Haskell incentivizes the use of “pure” functions, which don’t have side effects. Functional design forces the program to work as a whole, as opposed to object-oriented languages, where a lot of objects try to communicate with each other using these side effects, turning the app into an unpredictable mess. We’ve suffered this in C# and Unity a lot at work.

Denis Mirzoev: When the language’s naturally “lazy”, it’s generally more expressive. Algorithms get simpler. If intermediate results aren’t used, it greatly increases performance.

Igor Shevnin: The “laziness” often helps, but when the order of function calls is important, it’s sometimes really hard to understand what’s going on.

Doctor_Ryner: If it complies, it’s probably pretty fast.

Denis Mirzoev: Performance-wise it’s comparable to Java, but not as fast as C.

Igor Shevnin: It has extension support out of the box, which allows you to tailor the language and the type system to your liking. There are a lot of extensions that are widely used by the community and have decent samples and documentation.

Doctor_Ryner: The standard Prelude library has a lot of bad functions like read, head, readFile, which can throw out an exception and crash the app instead of returning Maybe. So I have to use alternatives or write my own.

Igor Shevnin: the biggest problem is lack of standards, to the point where a lot of people replace the standard library with one of the alternatives, which aren’t in any way compatible with each other. The community’s split on what the standard library should be, what has to be included in the core distribution and what can be offloaded to extensions… In my mind, it stifles development of the language.

Denis Mirzoev: It lacks tools: there isn’t a proper IDE, very few performance benchmarks, no “step-by-step” debugging — it’s a fundamental issue.

What projects is Haskell best fit for?

YS: For complex, security and finance-related tasks, where mistakes are expensive.

Doctor_Ryner: For everything where you need to compute, convert and analyze. I’m surprised Haskell is less popular in Data Science applications than Python.

IS: I wouldn’t risk using it for embedded systems (it’s fast, but there’s still significant memory overhead due to “lazy” computing) or small scripts (where its strict nature isn’t needed). It’s also important to understand how hard it is to find developers compared to mainstream languages.

John Doe: For writing industrial code that’s going to be read by others, but then you need an entire team of Haskell developers. There isn’t a lot of them.

IS: But thanks to it concise and strict nature you can use Haskell for almost anything.

Is it a good idea to start your development career with Haskell?

IS: Probably not, because the overwhelming majority of code bases a developer has to work with isn’t written on it.

John Doe: Bad idea! Non-ML languages — which is almost everything in industrial applications — would be a shock to you.

DS: Often people learn math first, and switch to programming later. So theoretically, learning a language that requires a lot of math concepts (algebraic data types, pure functions) should be easier than imperative languages. I think it’s a good idea.

Doctor_Ryner: All rookie developers I work with I introduce to Haskell first. People that don’t have the baggage of the imperative style are a lot quicker to learn functional code, and even when they work with object-oriented languages later, they tend to utilize good architectural solutions because they’re used to them.

YS: It’s best to start with a couple of fundamentally different languages, for example C, Haskell and Smalltalk, in any order. No one language could give you full understanding of the landscape.

Haskell is quite an old language. Is it good or bad?

YS: The language is developed very actively, it doesn’t drag the weight of backwards compatibility for the sake of it.

John Doe: it was standardized in 1998, but you wouldn’t notice: to this day, roughly every 6 months there’s a new compiler version that can potentially break backwards compatibility.

DS: Haskell isn’t old, it’s simply tried-and-tested. It doesn’t (and will never) introduce mindless changes. So it’s probably good for the health of the community.

It’s often said that Haskell is one of the toughest languages to learn. Is it really?

Doctor_Ryner: As a language itself — no. The hardest part are the abstractions it uses. A person who’s never seen a Haskell code before could go mad from the amount of new information and strange instructions. What doesn’t help is that the language “restricts” a lot of stuff that doesn’t fit its functional concept.

John Doe: It took me two months of bedtime textbooks, manuals and tutorials just to get my first project to compile. Though, once it did finally compile, it worked right away under full load (6k RPS average, with 15k peaks) for half a year with no changes whatsoever.

DS: I’d bet that if you give a college student Haskell as a first language and he goes far with it, then imperative programming would look complicated and less intuitive to him.

IS: It’s all relative. Out of mainstream languages, I consider C++ the hardest. Theorem-proving languages (like Agda or Coq) are harder than Haskell conceptually. Haskell isn’t a hard language, but it takes time to learn its pattern and libraries (both standard and third-party).

Is its complexity justified?

IS: Patterns and a high abstraction level are justified, since it makes code shorter and more durable. But I think operators, function names and a lot of other things could’ve been a bit user-friendlier.

Doctor_Ryner: Oftentimes Haskell’s complexity allows you to make very short, flexible and modular solutions.

YS: I’d say only effect control is a bit wonky, though it’s still almost always preferable to no control. And there’s an ongoing project to make it simpler.

John Doe: For people used to Python/PHP/whatever, Haskell feels dislodged from reality. For those you weren’t already interested in the theory of categories, it’s very hard to learn from scratch. But when you do understand it, you find a new approach to solving a problem.

It’s often said Haskell isn’t a language for developers, but for mathematicians. Is this the reason it’s not mainstream?

DS: It showcases the main idea of Haskell’s main developers — “avoid success at all costs”. Not meaning “avoid success”, but “avoid too expensive of a success”.

They could’ve made Haskell popular. For example, Microsoft supports the language. They could’ve made it more imperative, sacrifice rigidity for popularity. There are a lot of dirty tricks they could’ve used, but never did.

Sure, the language isn’t popular, but that means it’s quality doesn’t suffer. Advantages of Haskell compared to imperative languages are obvious to me and its problems can all be solved, so I believe it’ll get popular later on.

YS: Only people who don’t know anything about it say so. Haskell is used a lot in “real-world” development, you could probably find examples in your favorite search engine. In particular, we at Kaspersky Labs are very happy with Haskell and wouldn’t trade it for anything else.

IS: What’s a “mathematician’s language”? It’s either R/MatLab/Mathematica built specifically for statistics and calculations, or Python because it’s simpler and doesn’t require as much engineering background. But not Haskell. It has stuff from algebra, like monoids, but it has practical application.

The reason why C/C++/Java are so popular is because they’ve historically been very widespread in the enterprise space. They filled a niche. But nowadays a lot of companies start to use Haskell and other functional languages.

What PL would you compare Haskell to?

John Doe: out of the popular ones, probably with Erlang. But Erlang is simpler to learn and write in.

DS: I know C, C++, Java and Haskell. C++ is awful and can’t compare to anything. C is great for low-level development. In all other applications I’d prefer Haskell.

Choosing between Java and Haskell is harder, but it depends on the application. For example, Java is better for Android, but in server applications they’re almost equal. If the environment — tools, libraries — allow, I often choose Haskell.

Doctor_Ryner: I compare with C#. Just Google “how to do Maybe in C# and Haskell”. It’s strange that such a strictly functional language as Haskell feels a lot more flexible and free. But in reality, they’re the polar opposites.

C# is one of the most object-oriented languages, and its advantages go in contrast with Haskell. C# always forces you to write a lot of extra stuff, which slows the code down and often makes it less elegant. After Haskell’s short and neat solutions, it’s hard to go back.

IS: With Rust, and so far Rust probably wins. It takes a lot from Haskell and other functional languages, but mixes functional and imperative approaches, plus the developers have handled its development a lot smarter.

What’s your opinion on the Haskell community?

John Doe: The vast majority of people are very friendly and ready to help, which is a nice contrast to a lot of other languages.

Doctor_Ryner: Haskell communities are often full of terrifyingly smart people. Local memes about PhDs and academia exist for a reason. In other communities people mostly discuss regular production problems and data structures, while in a Haskell chat people discuss monads, applicative functors, crazy types and things like that.

You always learn something you never even thought about before.

It’s said that Haskell developers are too full of themselves. Is it true?

DS: Yes. I feel like it’s because they really like their language and are disappointed how unpopular it is.

John Doe: Nothing of the sort.

Doctor_Ryner: People probably say that because a lot of mainstream developers get annoyed with a Haskellist starts talking about functional programming and its perks. The Haskellist, meanwhile, gets annoyed that no one’s listening to him and start throwing terminology around, and thus gets labeled as “full of himself”.

IS: It’s a bit harsh to call them that. It’s probably because functional programming, OOP, differences between OOP-classes and union types, the extension problem and a lot of other definitions slowly build into one coherent picture, and then it’s hard to understand people who continue the holy wars of OOP vs FP.

Why are FP languages so niche?

DS: Their advantages aren’t enough to interest programmers. Being hard to learn doesn’t help matters, either. Tooling issues also scare people away, even though that problem would probably be solved if more people were interested. It’s a vicious cycle.

IS: Well, FP concepts slowly bleed their way into other languages…

Doctor_Ryner: The core principles of FP and its languages are fairly widespread already. Even Sharp has Linq and some other similar libraries. But purely functional languages probably just have too many novel concepts to be popular.

Don’t forget that 20 years ago the hardware wasn’t fast enough to handle functional languages yet, so it only entered the mainstream fairly recently, and Haskell itself is only growing.
Support the author
Share post

Comments 4

    The key failure of Haskell to appeal to masses is in the Second Hard Problem. Haskell has failed it miserably. (SHP — naming things).

    Why? Because no one knew WTF is monads. If you call this fancy set of structures and functions a 'thread' every one can get overall feeling what to expect. It starts, it twists, it ends. We can wave threads into something big.

    If 'this thing' is called a table, we can imagine something with fields to fill, rectangular in shape.

    What kind of casual properties give us Monad? What to expect from it? Well…

    — It's something obscure (check)
    — I don't know what it is in real life (check)
    — I feel I don't need it (check)
    — It provides a nice function composition (no check — how can I guess this by name?)
    — It allows to wrap values (no check)

    As you can see intuitive description of Monad is 'something obscure and useless'. How can language thrive when it build around such metaphor?

      For me the main issue with learning Haskell is the lack of real-world examples available. The tutorials are either something like “let f x = x + 5” or are explaining in-depth about the more obscure concepts like transformers, again without showcasing their practical real-world applications.

      ...and yet type output works well.

      Долго думал, что же такое «type output», и понял только переведя на русский и прочитав снова: всё таки, «type inference».

      P.S. Полное понимание данного комментария требует знания русского, не зависимо от, того, на каком языке он написан, а основной посыл поймут все.

      Only users with full accounts can post comments. Log in, please.