Lessons Learned From A Year Of Writing Haskell

Posted on January 3, 2021

The year in brief

This post

I’m writing this post as a collection of my thoughts on the last year, and a reflection on the major things I’ve learned.
The majority of my Haskell experience is in the form of writing code for web servers that talk to databases serve up APIs, although I am very interested in compilers and language research!

Outline

On The Practice of Software Engineering

Software engineering is about understanding the trade offs (performance, latency, domain modelling, et cetera), and implementing a solution that solves a problem with a solution space of development time, cost, and quality. Not every project you engage in will focus on code quality, but working at a company where some projects can focus on quality is a tremendous joy and enriching experience, and am very thankful to my teammates who made this possible!

One of the best exercises I had this year was going through my PRs and consolidating all the comments by theme, which taught me as much about my own code as what other people think about code in general.

An important perspective when writing code, is understanding how that software will exist through time, what demands will be placed on it, and how the fundamental assumptions will inevitably change. A big lesson for me this year is learning that a system can start out well, but through product mis-alignment, tight time constraints, and feature expansion, it can become an irreplaceable web of sadness littered through your code base too costly to remove!

On a psychological note, through trial and error I realized I only have so many “high performance” hours in a week where you can be sustainably productive without lowering the quality of the hours you work. Some corporations have even found workers are even more productive with 3 day weeks versus 5! source I’m not saying we should go that far, but when you’re home all the time coding in a pandemic, balance is key to staying fresh and effective!

Haskell Observations

Contributing to ghc is HARD!
It’s a complex and old code base, and although there is plenty of documentation, it takes a ton of work to be able to understand ghc well enough to contribute at the level needed to fix bugs and implement new features. That said, there is a ton of documentation work that still needs to be done, and is pretty beginner friendly work!

Use Template Haskell to generate code only as a last resort! The available alternatives, including deriving instances, have grown rich with options over the past few years, and these alternatives are less likely to eat up your compiler time or make cross-compilation an herculean task! Quasiquoters are a notable exception to this, as are inserting filenames/git commits at compile time, the key is to use it sparingly!

Haskell Planetarium as a link aggregation has enough content to be readable everyday, and along with Haskell Weekly are my goto sources of Haskell related content.

Next, and pretty obviously, you can use Haskell to deliver value in business. This is already established, but watching different teams write similar web services at their direction showed me that there is a lot of variety within the ecosystem.

Based on my experience, answers the following questions will vary from project to project, and asking them will get you oriented in a new project pretty quickly:

By the Expression Problem I mean which typeclasses are needed to be derived or defined, like ToJSON or serialization. I’d like to add that the overwhelming majority of effects I’ve seen have been handled using mtl and/or IO, but we appear to be close on extensible effects, and the work done on eff looks promising!

Musings On Type Level Programming

A theme for this year for me was exploring the intersection between type level programming and good software engineering practices. It’s one thing to know Haskell, it’s another to write beautiful code that’s as easy to understand as it is to maintain. As a prior, my stance on new, complex Haskell features is to “write junior code”. However, given a sufficiently experienced team familiar with type level programming, the trade-offs of the features themselves can be evaluated per se…

Haskell Type Level Solutions Worth Their Weight

Haskell Type Level programming ideas I’ve unsuccessfully tried to apply, but am holding out hope for…

Build Systems

I’m not sure what else to say here, other than build systems in Haskell leave something to be desired!
Stack works, but doesn’t cache well, and there’s the dreaded flat namespace error and related errors that sometimes are most easily fixed by manually removing the offending library, or worst case removing your .stack directories.
Alternatively, Nix is an efficient and robust build system, but is really complicated, and takes a non-trivial amount of time to learn and set up if you’re going to use that for your CI build system. I want to learn Nix and use it for personal projects, it’s just a question of priorities, and figuring out how to get it to work with ghcid.
In 2021, I should really try cabal :)

My development environment

The Haskell development environment has really improved over the last few years, and here’s the setup I eventually settled on:

The haskell development environment is getting better all the time, and although I’ve set up Haskell Language Server a few times for small side projects, I haven’t taken the time to try it on a larger code base, despite the extremely helpful project devs!

My ideal tool, would be something that consolidates the different search interfaces (hackage, regex on hackage, local search, jump to definition, et cetera), to create a utility that jumps to definition or docs given what’s in scope for a given module or even project.

The Year In Readings

Here’s a sampling of the “essential” articles I came across in 2020.

With a little help from my friends!

Articles and projects by my co-workers…

In Summary

2020 was stressful year that forced us to question many of the systems and institutions around us, including the Haskell ecosystem, it’s funding, and future direction. We celebrated the release of ghc 9.0.1 a major milestone, and look forward to the formation of the Haskell Foundation
It’s my sincere hope the Haskell ecosystem can continue development through means that are parsimonious and beneficial for society. Further, I hope 2021 is a year in which Haskell continues it’s improvements as a stellar industrial programming language, and the lessons learned over it’s first 30 years can be used to further programming language development for years to come!