I’m just a couple of months in, and have written my first production Haskell app, a PDF parser for Oregon laws. Programming it feels different, in a good way. Looking over the list below, two themes — easy and fast — stand out. Compared to OO languages:
- It’s easy to jump back in to previous work;
- easy to test my code;
- easy to refactor;
- easy to code in a familiar style;
- the programs are lightning fast;
- I’m delivering features faster;
- I can use Atom as an IDE;
- it’s simple to develop on a Mac and deploy on Linux,
- it’s easier to understand someone else’s code.
Plus, I just subjectively look forward to it. I think this all adds up to a low mental burden, yet the language is very stimulating.
I decided to focus on “benefits” because really, that’s what we’re all after. This may sound controversial, but I don’t think anybody “wants” referential transparency. That’d be like wanting a regular cleaning service. Instead, what we do want is the benefit; a clean home. Or in programming terms, a clean codebase. So let’s talk about those features now:
The features that enable those benefits
I thought a lot about why I’m seeing these benefits. Here’s a quasi root-cause analysis for them:
Easy to come back to a project and do a little work on it, because of low cognitive load, because everything I need to understand a chunk of code is on the screen in front of me, because of pure functions which have very clear input and output, and because my text editor (Atom) acts as a full IDE showing me the types of every variable and signatures of every function.
Easy to refactor, because I can simply cut and paste functions from one file to another, because there are no globals, only constants, and because the functions — pure and impure — are easy to compose. Also because I can change my data structures and the compiler shows necessary changes in the code, e.g. forcing that every property is set, and to the correct type. Because I can rename anything and the compiler shows every reference needing updating.
Easy to code in a familiar style, because new functions can be composed from others, and new operators can be defined — without sacrificing the other benefits.
I can develop on OS X and deploy on Linux, because the libraries are cross-platform.
The programs are lightning fast, because they’re compiled and because Haskell has lots of optimizations, like laziness.
I’m delivering features faster, because I’m writing much less code, and because I don’t need to write many tests. In Ruby, my test suites are perhaps 2-3x the size of my code base. In Haskell, I’m only TDD’ing and testing particular pieces which can be tricky to get right, like regex-based parsing functions. The compiler tests the rest for me automatically. I’m also writing fewer tests because the code itself is declarative (as well as type-checked). In other words, it reads like a test already, and so a test would only be redundant.
Based on my experience so far, Haskell’s my current language of choice for new server-side code.
I’ve decided to make this the first part in a series about my real-world experience of using Haskell for application programming. I’ll follow up with a post on some of the rough edges in the ecosystem to be aware of, and the best path I’ve found for learning Haskell.