Haskell has a strong tradition of blending a research and pragmatic language. GHC, the flagship Haskell compiler, continues to explore cutting edge language research. The flexible type system encourages people to explore new ideas in libraries. At the same time, production software is written and run around the world in Haskell.
FP Complete falls squarely on the pragmatic side of this spectrum. We're here to make production-grade commercial software, and help others do the same. Our philosophy is based in that world. Our overall goal is to reap the huge benefits of Haskell while minimizing risks.
As a company, when we analyze how to approach a project and which tools to use, we want to maximize benefits (efficient runtime, productivity, etc) while reducing costs (learning curve, project risks, etc). Some general recommendations for this include:
- Respect the novelty budget
- Make sure you understand the business requirements, not just technical requirements
- Follow the 80% rule: use things that deliver 80% of the value, and don't try to optimize for that last 20%.
In 2018, Michael Snoyman, Vice President of Engineering at FP Complete, wrote up a document called the "Boring Haskell Manifesto," which captures a lot of these ideas.
Haskell is in many ways a revolutionary language. Many languages in widespread use today are incremental changes on previous languages. However, Haskell doesn't fit this model. Concepts like referential transparency, purely functional programming, laziness, and immutability are a stark departure from common programming approaches today.
Most any Haskeller would argue that these radical changes are well justified, and deliver great benefit. At the same time, this inherent culture of making revolutionary changes attracts a certain mindset to the language. As a result, we end up in a situation where Haskell has essentially two distinct (and overlapping) subcultures:
- Explore interesting and revolutionary concepts in computer science, software engineering, and mathematics
- Make better software
Again, these are overlapping subcultures. The entire history of Haskell is cases of esoteric, academic, intellectual, and "useless" concepts becoming an elegant solution to challenging problems. Monads are probably the most prominent example of this, and we're seeing a reality where many other languages are slowly adopting the concept to solve problems in concurrency and error handling.
On the other hand, not every new concept turns into one of these fundamental and useful techniques. And even for those that do: finding the most practical way to leverage the technique is an arduous, time-consuming process.
Exploring these concepts can be fun, rewarding, and—long term—a huge benefit for productivity. Short and medium term, however, this exploration can lead to slower and less reliable results. As a company or project manager assessing Haskell for a project, this uncertainty can thwart the possibility of adopting Haskell.
We're now faced with a situation where Haskell is often eliminated for usage, representing a massive loss for two parties:
Companies, projects, and managers could have realized great benefits in productivity, reliability, and performance from the less revolutionary pieces of Haskell. Instead, they're losing this competitive advantage.
Engineers who would much prefer working in Haskell—even its less revolutionary subset—are unable to do so because of employer fears of choosing it.
We'd like to improve the situation.
The Boring Haskell Manifesto
Our claim is simple: for many cases of software engineering, a simple, well-defined subset of Haskell's language and ecosystem will deliver large value for a project, while introducing little to no risk compared to alternative options. We call this subset, somewhat tongue-in-cheek, "boring Haskell." Our goal is to:
- Define such a subset
- Provide straightforward documentation, tutorials, cookbooks, and libraries that encourage this subset
- Continue to evolve the subset to optimize its best practices
- Help interested engineers to learn how to use boring Haskell, and get it adopted in their companies
The most concrete step in this direction is creating the rio library, which is intended to capture these principles. If you want to embrace Boring Haskell today, we recommend using that library. The rest of this document discusses what we believe counts as "Boring Haskell," and motivates these choices.
We want to analyze the features of Haskell that we recommend based on its power-to-weight ratio, also known as a cost-benefit analysis. Put more directly: we want to choose features which provide lots of benefits while minimizing costs. Let's give some examples of these two sides:
- More maintainable code
- Less bugs in production
- Higher performance
- Higher productivity
- Learning curve
- Ongoing cognitive overhead
- Ongoing tweaking
- Slower compile time
- Poor performance
A concrete example of something with a great power to weight ratio are sum types. Sum types are a relatively simple concept to explain. Most people can grok the concept almost immediately. Pattern matching feels natural fairly quickly. And sum types solve large classes of problems people regularly encounter in programming tasks.
- Support is available
- We can hire people
- What’s the cost of hiring people full time/what’s the cost of training
- We can do rapid discovery in Haskell, then rewrite in something “less risky”
- Learning Haskell makes your engineers better engineers
- Escape hatch from Haskell if you hit a wall
- FFI to C/Rust
- Feel free to drop down to imperative Haskell