Haskell is a Bad Programming Language (2020)

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • SaaSHub - Software Alternatives and Reviews
  • ihp

    🔥 The fastest way to build type safe web apps. IHP is a new batteries-included web framework optimized for longterm productivity and programmer happiness

  • pandoc

    Universal markup converter

    Haskell is fantastic for programming systems where types are not just a tool, but central to the goals of the program. E.g. a program for converting one type of markup files to another (from one type to another type), like pandoc [1], which indeed is written in Haskell.

    [1]: https://github.com/jgm/pandoc

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

  • advent2020

    Solutions for Advent of Code 2020. (by elldritch)

    Haskell has a lot of problems, but this article is not good, and does not describe them well. It reads like someone who has tried Haskell, and has sort of written some code in it, but has mostly been put off by bad and confusing tutorials, and has never really grokked the language. Indeed, look at the author's GitHub - of their 50 projects, only 1 is Haskell, and that is a handful of commits before giving up.

    My main complaint with Haskell is that it's actually a great language, wrapped up in (1) hilariously beginner-unfriendly syntax and tooling, and (2) a library ecosystem that does not quite understand the value of friendly documentation (although this is actually improving a lot). There are also some weird warts around the language itself, but those are mostly tolerable and not so much worse than the weird warts in all other languages.

    My specific complaints about beginner-unfriendliness in syntax and tooling:

    - The compiler will infer the types of names as generally as possible, and will run this inference both forwards ("this variable started as a string, so must be a string now") and backwards ("this variable is used as a string, and therefore must have been a string earlier") depending on what information is available for inference. This means that type errors are hit-or-miss -- about 60% of the time, the type error will point you to your actual mistake, and the rest of the time

    - The syntax is VERY minimal, and prefers minimalism over readability. In particular, Haskell has no explicit parentheses for function calls, and has implicit currying! This means that it is very easy to accidentally get the arity wrong in a function call (for example, `foo (bar baz)` and `foo bar baz` mean very different things!), and create an extraordinarily confusing type error.

    - This minimal syntax also means that you can sometimes type something that is _almost_ correct, but is actually valid syntax that means something totally different! In some of these cases, you may even type something that is not syntactically valid vanilla Haskell, but _is_ valid Haskell-with-some-extension, and the compiler will unhelpfully suggest that you turn the extension on even though it may not be what you want (and also provides no explanation of the extension).

    - The compiler tells you what expression has a type error, but never actually tells you the exact term that has a type error. You have to sort of guess at this by understanding the rough high-level of how the type inference works. It's something you have to really pick up, and is hilariously unfriendly compared to e.g. `rustc --explain`.

    - Print-debugging works differently than what you'd expect. Nobody ever teaches you that `trace` is a thing (seriously, this should be thing #2 that is taught), and nobody ever teaches you that "you might get trace messages in a different order than you expect because Haskell is evaluating using graph reduction, not evaluating in the order of the lines of code you wrote").

    Really this boils down to: even though Haskell will do a very good job at preventing you from holding it wrong, you really do have to _have a decent grasp on what you're doing_ to write a program. As a complete beginner, you can't just put something you think will mostly work and then rely on good compiler errors to tell you where to spot fix. (Fortunately, this gets much better over time - you learn how to interpret compiler errors better as you get a grasp on the language, and you learn tricks for building incrementally correct programs up using `undefined` and friends).

    My specific complaints about documentation:

    - Contrary to this article, types actually ARE decent documentation in Haskell. The constraints you can do with types in a pure language are much, much stronger than in other languages you've used before. Trust me - this is a Blub paradox thing.

    - Unfortunately, although types do a great job at preventing me from plugging the pipes together wrong, they still don't tell me anything about the _semantics_ of a function. Lots of older libraries do a very bad job at documenting semantics, but this is getting a lot better.

    - Arguments in Haskell functions are not named (or at least, their names are not exposed in documentation). This makes for some confusion sometimes - what arguments should your `foo :: String -> String -> String` take?

    - Lastly, a lot of libraries document very academically. Here's an example: https://hackage.haskell.org/package/logict-0.7.0.3/docs/Cont.... The documentation here is written assuming you understand how Logic computation works, provides no examples, and you're supposed to read the module documentation and actually _go and read the paper_ (in fairness, it's pretty short) that they've linked. This is a far cry for NPM world, where everybody has a quick start.

    Overall though, it's a really good language. Once you get monads (and a HUGE part of this is not the idea of monads, but the really unfriendly syntax and error messages of Haskell), a lot of things make a lot more sense. It's my regular side project driver.

    Lastly, a word of advice to anyone looking to actually make a good-faith evaluation of Haskell: try it, make something substantive, and stick with it until you actually grok it. Seriously, don't just pick it up, get stumped by error messages, and give up. The tooling is very beginner-unfriendly, but fortunately the humans over at the Functional Programming Slack (https://fpchat-invite.herokuapp.com/) are VERY friendly. As a first project, I'd recommend doing the Advent of Code, or building a small web application (IMO with Scotty, which feels like Express, rather than Yesod, which feels like Rails. Yesod is almost certainly better in production, but has a different and IMO less instructive learning curve). If anyone needs help, follow along with my AoC 2020 (https://github.com/liftM/advent2020), although be aware that some things I do there are a bit fancier than necessary.

    I find that articles like this that complain about things like type obsession or the academic focus really are not representative of the actual pain points with Haskell, and are FUD more than useful. Yes, the tooling is beginner-unfriendly. Yes, you will probably need to ask some questions on the FP Slack on your path to learning, things that a friendlier language would have documented. But this mystical aura of "ooh, there are types and they are very abstract!" is not reflective of reality, is not a criticism grounded in the reality of writing Haskell, and IMO is misleading for people genuinely trying to assess the language.

  • haskell-ux

    Let's make Haskells error messages helpful :)

    > I think that Haskell is a great language to prototype pure business logic because of the type system and focus on purity, but it has several warts, because haskellers focus more on language research than DX.

    This is very true. We recently started https://github.com/digitallyinduced/haskell-ux to keep track of haskell DX improvements. Some of our suggestions are already issues on the GHC (haskell compiler) bug tracker.

    Here's an example of a great UX improvement in GHC: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4711

  • ghc-proposals

    Proposed compiler and language changes for GHC and GHC/Haskell

    > some things are almost comedy

    We're trying to fix that! https://github.com/ghc-proposals/ghc-proposals/pull/351

  • penrose

    Haskell to JavaScript compiler, based on GHC

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts