Simple Haskell is Best Haskell

Image for post
Image for post

Almost two years ago, I moved from a cushy corporate Scala job to a riskier mid-stage startup using Haskell. This post summarises my thoughts about Haskell after experiencing it first hand.

The Good

The Haskell build and runtime analysis tooling is on par, if not better than, industry standards for Enterprise languages.

The Haskell compiler is rock solid, very fast, produces high performance output, and gives excellent compiler warnings and errors, unless you stray into experimental language features.

The Haskell documentation, and ease of learning from scratch, is comparable to mainstream languages. That is to say, a programmer with zero knowledge of Haskell can learn from a textbook (Graham Hutton’s is best) combined with an offline course or toy project. Alternatively, paid on-site training is available. Note that many EU and UK computer science graduates learnt Haskell as part of their studies.

The editor support is pretty good and is making progress. The language itself is designed to be easy to write tooling for: a static analysis of a file’s header will reveal all that is needed to fully qualify any symbol used in the file, and a very open compiler api allows for a REPL and LSP implementations. Many people soon realise that an IDE is not as necessary as it is in other languages.

Strong typing means everything can be indexed, and that means it can be searched, via Hoogle. Speaking as a huge Lisp / Scheme fan, types get in my way and slow me down on one-man projects, but discoverability is the thing that makes up for it. Of course, the benefits scale to larger projects, when the type safety comes into its own.

The Bad

Haskell was designed as a research language and the main implementation (ghc) has many language extensions, often being the output of a PhD thesis. Decomissioning is harder than releasing, so it is rare that anything is ever removed.

This constant desire for “better” and “further” is reflected in the community, which outputs a lot of foundational frameworks and has neverending technical debates on the smallest of details: let a hundred flowers bloom! Unfortunately, that is incompatible with industry which demands clear, opinionated, guidance on how to structure an application.

This is also reflected in the community’s overabundance of conscientiousness thinkers and inspirers, in Marston’s parlance, making it more difficult to create a well-balanced team (I’ve been lucky to be part of an intentionally well-balanced team, but this is not the norm). A naively constructed team risks failure by getting caught up in the details, or building ivory towers, rather than making progress towards business-critical goals. Contrast this to the Python community, which has an overabundance of “get shit done” personality types, tending to produce tangible results in the short term, but unbalanced in other ways.

The Ugly

Ultimately Haskell hasn’t gained critical mass, despite being 30 years old. All the approaches to grow faster are failing.

I believe that the reason why Haskell is still niche is not a technical problem but a social one.

There is a widely held misconception that Haskell is difficult to learn, is slow, and has terrible developer tooling. It is impossible to fight a misconception without a gigantic public relations budget, or a lot of education and a lot of time and patience. Moreso when the perfectionist camp of the Haskell community can be trusted to “well, actually…” any suggestion that the tools are production ready, i.e. the community is adept at shooting itself in the foot.

The Graveyard Scene

Image for post
Image for post
(This is where the good guy shoots the bad guy, and then finds the gold)

I believe that initiatives like Simple Haskell may go some ways towards addressing the widely held misconceptions of Haskell. But it will take time, possibly even so long that advances in computing architecture make Haskell obsolete.

A more radical approach, that has only a very small chance of success but could advance the timeline, would be for the Simple Haskell initiative to create their own compiler, possibly with its own branding, that offers the carrot of compilationand runtime performance (e.g. Unison style AST hashing and whole program optimisation) and editor tooling. The reduced language footprint implies a simpler ecosystem to meet the constraints, with fantastic onboarding documentation to match it. A strict subset, not a split.

To be clear, such a compiler should not pander to newcomers. It’s not about “dumbing down” Haskell: a conservative compiler would target experienced industrialists who have different requirements than the fantastic research community who want to explore uncharted territory. Such an effort would need to be very careful to remain on good terms with the ghc research community: it would not be competition but rather complementary. Wildly successful extensions could be ported over on a much slower timeframe: for example if a record encoding comes along that addresses all the current shortcomings.

By remaining fully standards compatible, it should always be possible for a team to swap from this “simpler” compiler to ghc if it proves to be too spartan for their needs.

I propose an even smaller subset than their recommended language extensions, stopping short of DeriveGeneric and GADTs, and not allowing orphan instances or non-total fields in sum types. The most common usecase for generics is JSON serialisation / deserialisation and that can be achieved with a really good boilerplate generation tool. Typelevel programming is where most people get off the static typing hype train, and where the compiler's error messages start to go off the track.

Update: excluding DeriveGeneric, which is not part of Haskell98 or Haskell2010, seems to be a step too far for a lot of people. I do not believe we have explored enough alternatives for everyday usecases, like JSON encoders. I am interested in exploring tools (compatible with ghc) for boilerplate code generation of typeclasses, e.g. following a Divisible / Decidable / Applicative / Alternative formalism, as explored in scalaz-deriving. It could replace all the various Derive* extensions.

I also think that Haskell needs to have a trusted compiler that can be compiled from a more fundamental language (one that compiles from C). Scheme, Typed Racket and Swift are the best mainstream candidates I can find; Nim and Shen would be interesting. Otherwise the language becomes “trapped in” to historical binaries and it becomes impossible to verify that the entire ecosystem hasn’t been compromised. Joachim has some thoughts on this, and it may be possible to ressurect the Hugs Haskell98 compiler, which compiles from C. Hugs has proven that the community does not want to maintain a compiler written in C, but it could perhaps be used to bootstrap a much reduced ghc, or from-scratch alternative.

But who would fund such an effort? There is no money to be made from a compiler, so it will not be funded. Therefore, I must sadly accept that the compiler will not be written, and will not be popularised even if it is written. We are living in the “a lot of education and a lot of time and patience” world.

Ultimately, Simple Haskell should not be such a controversial idea: imagine asking C developers to stick to the C18 standard instead of depending on internal details of gcc or LLVM. The reason why nobody wants to do that in Haskell is because there is no payoff, therefore people reach for the implementation extensions.

I am not a programming language evangelist, but what I will say is this: if you are a decision maker, and have a team who would gladly use Haskell for your next project, then please be open to their suggestion. Make sure that your team has a good mix of personalities, ask them to stick to Simple Haskell, and you may be pleasantly surprised with the results. As a bonus, you will be able to attract amazing talent that you currently don’t have access to!

Chartered Mathematician, Haskell, Free Software. Author of https://leanpub.com/fpmortals

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store