Haskell in Production: RELEX Solutions
In this edition of our Haskell in Production series, we sit down with RELEX Solutions, a supply chain & retail planning platform. In this interview with Serokell, Lead Software Developers, Mats Rauhala and Martin Potier, shared with us their reasons for choosing Haskell for their project and their experience implementing it.
Could you give our readers a brief introduction to RELEX Solutions and your role there?
Martin: RELEX Solutions edits a fairly complete supply chain & retail planning platform. One part of this platform, called Plan, deals with retail supply chain optimization. Plan helps our customers decide how much goods to order, for which store and when. This enables our customer to reduce spoilage due to long stay in storage and to avoid shortages due to empty shelves, so that the product you want is always available on the shelf. Our team deals with automating the deployment tasks related to the lifecycle of Plan applications.
Where in your stack do you use Haskell?
Martin: Our software is used by other engineers to deploy and configure the RELEX Plan software which is sold as a SAAS for our customers and runs on our private cloud. The software bundles the configuration and executable and applies it to the servers in a declarative and immutable form.
How did you decide to choose Haskell for the project?
Martin: When I and Mats started at Relex, Haskell was already used for the current deployment tool for Plan at the time. From what I’ve gathered, it was initially created by a handful of technical customer people, to scratch an itch. An early version of the tool was a Ruby project, Go was considered, but ultimately the Haskell version stuck and grew. When the time came to build the current iteration of the project, Haskell still seemed like the most relevant choice for building a reliable web service.
Are there any specific qualities of Haskell that make it well-suited for the particular use case?
Mats: I’m looking at this from a different angle; why wouldn’t we choose Haskell? I believe Haskell is an especially good general-purpose language and should be part of consideration for any project unless the use case is particularly unsupported by the ecosystem, such as gaming or embedded devices.
Haskell and especially the Haskell ecosystem focus on reliability and correctness while still remaining reasonably performant. This lends itself well for production systems, even if you every now and then have to spend some more time and effort for implementing things that might already be implemented in other languages. In addition to reliability and correctness, there are some noticeable maintainability benefits through the type system and excellent testing libraries which have allowed us to do some larger refactorings and rewritings on occasion.
It’s difficult to detect the absence of bugs, but I’m confident in saying that we have been able to write reliable software with very few bugs. Most of our runtime problems are related to some external system failing every now and then.
Did you run into any downsides of Haskell while developing the project? If so, could you describe those?
Mats: Most of the things that people warn online such as laziness, memory leaks, hiring haven’t been problems so far. The biggest problem we have faced relates to upgrading the dependencies. I can classify the problems to three categories:
- Libraries no longer compiling.
- Libraries compile but their public signatures have changed.
- Libraries compile but their behavior changes.
The first issue is annoying, requiring one to patch the libraries. If lucky, the library still has an active maintainer and you can attempt to upstream the fixes, otherwise you’ll end up dragging a fork of the library or keeping track of patches.
The second issue is usually quick and somewhat mechanical to resolve.
The third issue is terrifying as it’s a potential invisible change. Any library that has changed has the potential to suddenly cause breakage. I can remember two cases that wreaked havoc, the first one was with the GHC/base library where
threadDelay maxBound overflowed and ended up in a busy loop, and the second one was upstream fixing a bug in http-client which we were apparently relying on.
Then there is the more organizational issue of keeping the codebase easy enough to understand. Haskell is a cool language with plenty of neat abstractions. You have your free and freer monads, profunctors, lenses, kan-extensions, type-level programming etc. It’s easy for a developer to introduce their favorite abstraction to the codebase, to the chagrin of others. One should keep in mind how these affect the complexity budget.
It seems that you also use JVM technologies at RELEX Solutions. How do these technologies play with Haskell? Do you run into issues of having FP and non-FP teams?
Mats: Besides a very small gRPC API, and a REST API, our tool doesn’t interact with the JVM software directly so there haven’t been any issues with interoperability yet. The problems faced are more organizational in nature, where our team should be the domain experts on all things related to RELEX Plan while we are narrowly focused on our own stack. On the upside, we have the possibility to cross-pollinate the other teams with functional programming idioms such as immutability and purity.
Do you have any in-house training programs to teach or upskill Haskell developers?
Martin: Nothing official at least, but it also hasn’t been an issue so far as all the hirees have been of excellent quality and each is eager to improve themselves. As the lead developer, it has been amazing for me to see how fast each and every member of our teams have grown the past years. What we do have is an encouraging atmosphere for learning through occasional workshops, group brainstorming sessions and pair coding.
What tips would you give for teams that want to start including typed FP languages in their codebase?
Getting a Haskell project greenlight involves a lot of luck and an explorative atmosphere in the company. If you do, however, manage to get a project started, you might be inclined to use all of your skill to create the greatest and bestest project of them all, using all the techniques you have at your disposal. Try to avoid this, stick to the basic skills and techniques instead, since it’s a bad tradeoff for the company to spend resources on a project that can only be modified by a set of elite programmers. Trade effect systems to simplicity, trade type safety to simplicity, trade abstractions to simplicity, keep the codebase accessible to juniors.
- Could you give our readers a brief introduction to RELEX Solutions and your role there?
- Where in your stack do you use Haskell?
- How did you decide to choose Haskell for the project?
- Are there any specific qualities of Haskell that make it well-suited for the particular use case?
- Did you run into any downsides of Haskell while developing the project? If so, could you describe those?
- It seems that you also use JVM technologies at RELEX Solutions. How do these technologies play with Haskell? Do you run into issues of having FP and non-FP teams?
- Do you have any in-house training programs to teach or upskill Haskell developers?
- What tips would you give for teams that want to start including typed FP languages in their codebase?