Haskell in Production: Riskbook

To continue our series on Haskell in production, we have an interview with Jezen Thomas, the CTO of Riskbook.

Riskbook is a marketplace that connects reinsurance brokers and underwriters, and Haskell has been working out quite well for them. In the interview, we talk about how Haskell can be a blessing when introducing changes to the codebase, what libraries and extensions they use in their project, and what are the downsides of choosing Haskell which you should consider.

Tell us about your company, your department and your own role there.

My name is Jezen Thomas, and I’m the CTO and one of the co-founders of Riskbook. We’re building a marketplace product for the reinsurance industry. This essentially involves enabling reinsurance brokers to create risk programmes and then market them to underwriters, all within our online platform. A risk programme has a fairly complex life cycle, and we model and digitalise all of the steps that professionals in the industry would traditionally have done on paper, which is of course far less efficient and far more expensive.

I’m proud to say that we have attracted a distributed team of truly brilliant people, we’re backed by some top angel investors and venture capital firms, and we have early traction with some of the biggest businesses in the industry.

What was the biggest challenge you’ve overcome while working on this project?

I think the biggest challenge we face is not unique to us — we want to quickly build robust software on a modest startup budget. I can say we have overcome this challenge to some degree; we’ve managed to hit several key milestones and our investors have so far been super impressed with how much we managed to do with so little, but carefully balancing where you invest and where you take on technical debt is something that persists through the life of a business. We’re not solving any wildly complicated problems at this stage of the business — at least relative to what many startups in AI/ML/Crypto-land are doing. We’re just trying to delight our users and build the kind of company we all would love to continue working at.

Haskell in production examples

How did Haskell help you to solve it?

Haskell and GHC give us an enormous amount of leverage even though we stick to writing fairly boring Haskell code. The type-checker enables us to quickly make broad, sweeping changes to the codebase with a relatively high level of confidence. Business is all about adapting to change — especially when you’re a startup — so having the facility to rapidly shuffle things around is crucial.

Furthermore, we are lucky to have such a rich package ecosystem. While we have contributed some features and patches to open-source libraries, we are overall very happy with the libraries we make heavy use of, e.g., Yesod, Conduit, and Persistent/Esqueleto.

What are your key takeaways from this project at this point?

The people who founded Basecamp (formerly 37 Signals) aren’t crazy. We run Riskbook quite similarly to the advice offered in their book Rework, and I strongly recommend anyone starting a business read that first. You can build an excellent business by hiring a small team of smart people, taking care of them, and listening to them. Hire remote, and don’t inundate people with synchronous meetings. Haskell in industry: Riskbook

Haskell is absolutely production ready. Yesod is an excellent web framework (though there are others too), there is good documentation freely available online, and there are plenty of friendly people around the world who can help you get started.

Simple traditional web applications still work great. For most business applications, you don’t need a distributed microservice system that serves up a JSON API for consumption by a complex JavaScript application that runs in the user’s browser. This may be contrary to what many people in the usual online programmer haunts might have you believe.

Do you support your project with an in-house development team or an outsourced one?

Good question. We don’t consider our team to be outsourced, though we are geographically distributed with people in the United Kingdom, Canada, Netherlands, and Ukraine. We don’t believe that having everyone co-located in an office is necessary for social cohesion, and it is most certainly to our benefit that we are able to hire from just about anywhere in the world. That said, we do appreciate that a good social bond is important for a team of professionals, and in November of 2019 we flew everyone on the team to Belgrade, Serbia, for a week of learning more about the reinsurance industry, and generally spending time together. We plan to have the team meet up in exotic locations more frequently as our company matures.

Risbook team haskellers

Could you describe your technology stack? Which Haskell language extensions / libraries do you tend to use most often?

Riskbook is a partially event-sourced system written with the Yesod web framework. We lean on GHC as much as we can, while constantly trying to balance robustness with development and maintenance cost. We’re using the yesod-test framework for fairly high-level integrated tests, and Hspec otherwise. We would like to invest more in property-based testing.

Most interactivity is implemented with server-side templating in an orthodox RESTful style (where that makes sense), though more stateful user interface components of the system are implemented in Elm.

Our data persistence strategy depends on our tolerance for volatility, and data ends up in one or more of PostgreSQL, Redis, and Haskell’s native software-transactional memory.

Our infrastructure is managed with the Nix ecosystem of tools, meaning our network of machines on AWS run NixOS with immutable file systems, which are built to a declarative specification and deployed atomically with NixOps. New machines can be provisioned and deployed with a single command.

As far as language extensions, I ran the following command to measure our usage:

grep -rh '^{-# LANGUAGE' . | cut -d ' ' -f3 | sort | uniq -c | sort -nr

This returned the following results.

 102 TemplateHaskell
  85 OverloadedStrings
  65 TypeFamilies
  52 DeriveGeneric
  51 GADTs
  49 MultiParamTypeClasses
  47 RecordWildCards
  46 GeneralizedNewtypeDeriving
  38 UndecidableInstances
  33 FlexibleContexts
  28 FlexibleInstances
  25 QuasiQuotes
  18 DataKinds
  16 LambdaCase
  16 DeriveAnyClass
  15 TupleSections
  14 RankNTypes
  13 ScopedTypeVariables
   5 ConstraintKinds
   4 ViewPatterns
   3 TypeFamilyDependencies
   3 Rank2Types
   2 DefaultSignatures
   1 TypeOperators
   1 TypeApplications
   1 StandaloneDeriving
   1 PackageImports
   1 KindSignatures
   1 InstanceSigs
   1 DerivingStrategies
   1 CPP

If I hadn’t measured, I probably would have forgotten that Yesod does indeed make quite heavy use of Template Haskell to generate code. The core of our application is still only a humble ~17,000 lines across 182 files — not counting some external libraries we maintain — but if you were to dump the splices generated by Template Haskell we would be looking at approximately 160,000 LOC.

It’s worth mentioning also, however, that the numbers above are not truly representative. For example, we use the Persistent library, and we split up all our models into separate files.

We use generics and instance derivation where we can to make the codebase more ergonomic to work with, and some non-controversial syntax sugar too like RecordWildCards and LambdaCase. Nothing too crazy happening here.

We only have one language extension enabled for all modules (and declared in our Cabal file), which is NoImplicitPrelude. We generally opt for ClassyPrelude instead.

As for libraries, I think a large chunk of our work leans heavily on lens, aeson, conduit, persistent/esqueleto, safe-money, shakespeare, and hedis.

Where is Haskell great to use and where does it fall short in your stack?

For this and the following question, I had a chat with my colleagues to try and produce a more representative answer. We feel that Haskell is an excellent match for medium to large sized projects where prototyping speed and robustness are highly prioritised. Our workflow is highly ergonomic, and the refactoring story is best in class meaning it is relatively cheap for us to quickly adapt the software to changing requirements.

Where our technology arguably falls short is that with the combination of libraries and language extensions we use (and I doubt we are a special case here), some parts of the codebase may feel more imperative and less like classic plain Haskell. Of course, any business (and by extension, commercial software project) is going to be full of trade-offs.

Are you satisfied with the result or do you still have some difficulties?

It’s both. Overall we are thrilled with Haskell-the-technology, and also Haskell-the-community. Almost everyone else in the community has been exceptionally warm, helpful, and generous with their time. I think Haskell-the-technology is also far more pragmatic than it’s typically given credit for. Indeed we originally chose to use it not out of theoretical self-indulgence, but simply because we think it’s cheaper at any time scale.

It’s not all unicorns and roses — we still face some runtime errors (as anyone inevitably will), and the less-than-ideal compiler performance sometimes necessitates inconvenient project restructuring. But on the whole, I think we’ve made the right choice and we’re excited to continue in this direction.

We’d like to thank Jezen Thomas for finding the time to talk with us.

If you would like to speak about your industry project that uses Haskell (or any other functional programming language), we’d be pleased to hear about it! Our email is always open: hi@serokell.io.

Haskell courses: everyday extensions
More from Serokell
haskell to core thumbnailhaskell to core thumbnail
Haskell in production fossaHaskell in production fossa
haskell in production Haskoin thumbnailhaskell in production Haskoin thumbnail