I have been making my products statically linked over the past few days. This post presents why and how to statically link your Haskell executables and collects a mapping from obscure error to unexpected fixes. This work would not have been possible without the many-year-long effort of people like nh2 . This issue on GitHub is a good summary of what went into making this possible. Why statically…
Mutation testing is now generally available in sydtest . This is a major step towards a saner development workflow in the age of AI-generated code. What is mutation testing? Mutation testing aims to improve a test suite by automatically mutating code and asserting that the tests start failing. Alternatively: Mutation testing is like a type-system for your tests. It asserts that the tests test the…
My blog post " The purpose of Continuous Integration is to fail " got to the front page of Hackernews yesterday, and I was surprised by how little traffic that generated. It all started when I noticed that more people were scheduling demos on NixCI than usual. Luckily I had set up monitoring and alerting recently, so I was able to figure out what was happening by looking at my logs: Indeed there…
I've had another opportunity to write a blog post about CI: CI should fail on your machine first It's been more popular than some of my other blog posts have been so far, and I think it's because I decided to write about much less controversial topics. I'll be writing more about CI in the near future, so feel free to subscribe to the RSS/Atom feeds on the NixCI blog if you want to read more about…
A review of my 2025: family life, NixCI, and a new workstation. Highlights Family life continues to be amazing. I got to continue to work on NixCI. I built a new workstation. I collected 35 new failures Family Ever since our daughter was born in 2024, I've been fortunate enough that family life has taken up most of my time. This year's post will therefore be short on other topics. It will also be…
This post is the end result of a year-long nerd-snipe caused by a real problem: How can I be sure that I am told when my site goes down, when the service that tells me can also go down? Strange issues I host multiple services on multiple servers: This site NixCI Social Dance Today Intray Tickler Smos These have been running for anywhere from two years to eleven years. Over that time, all sorts of…
This post serves to show that Nix does not guarantee that builds are reproducible so that we may learn and improve our builds . Some of the following problems are not solvable. In such a case there may be ways to mitigate some of them. However, it is important that we don't lie about them when evangelising Nix. Why bother writing this? I have been building and deploying software with Nix since…
A review of my 2024: our daughter was born, signing in NYC, and new libraries. Highlights Our daughter was born I collected 78 new failures We signed with native signers in NYC I wrote 5 blogposts announcing multiple new libraries I built a home gym Daughter My partner and I were blessed with our daughter Lia in October of 2024 and we are oh so grateful. She is healthy, happy, and does a good job…
Answer: With <- You get the String out of the IO String with <- . Example in GHCI You have getLine :: IO String and you want to get the String . You can't "just" let line = getLine :: String because then you'll see: <interactive>:3:12: error: [GHC-83865] • Couldn't match type: IO String with: [Char] Expected: String Actual: IO String • In the expression: getLine :: String In an equation for…
This post announces autodocodec-nix , a new companion library for autodocodec that lets you generate a NixOS module options from any Codec . Every one of my products comes with some sort of Configuration type that has a HasCodec instance. The autodocodec library lets me easily generate documentation for this type. However, I then write a nix/nixos-module.nix that a NixOS option and type that…
This post announces opt-env-conf , a new settings parsing library for Haskell. This library combines the best of optparse-applicative , envparse , and autodocodec , together with the colours from safe-coloured-text to provide all your apps' runtime settings. Parsing Command-line Arguments, Environment variables, and Configuration files In just about any application I've worked on, I've always had…
This post announces the weeder-nix library for running weeder on a set of Haskell packages in Nix. Why weed? Over the years, your code will experience positive pressures. That is to say there will be pressure to add more code to it. In order to keep the code simple, there also needs to be negative pressure, i.e. pressure to remove code. Otherwise you will end up with hundreds of lines of code that…
A review of my 2023: moving in together, R&D engineering, and 134 new failures. Highlights I moved in with my lovely girlfriend. I collected 134 new failures, a new record! I worked as a research and development engineer. I built an off-site backup system We taught salsa dancing in two countries, danced in three more, and gave a workshop at Google. I wrote 12 blogposts. Work & time off I had some…
Turn signals on cars have a dangerous flaw. This blog post explores that flaw, proposes a solution, and digs into what we can learn from it to build better software. Traffic lights Before we look at turn signals, we first need to discuss traffic lights as an example of a system that got it right. Traffic lights operate in the following states: Red: Stop Green: Go Yellow: Stop if possible because…
This post introduces a testing technique called golden tests, snapshot tests, or characterisation tests . The technique can be a handy tool in your testing toolbox for maintaining invariants across versions of a piece of software. Introductory examples Golden tests are applicable in a surprisingly wide range of scenarios. Here we will look at some examples before digging into what they have in…
This post outlines a pattern that robust upgrades of running software systems have in common. Upgrading systems Real-world software systems can get very complex, but for the purposes of this blog post, it will suffice to describe a simpler system. Imagine a simple distributed system with one client and one server. The client can send requests to the server and receive responses. The server cannot…
This post announces the conformance library factored out from ical . It implements RFC 2119 in order to help you write implementations for other specifications. The conformance library exists to let you write a single parser that you can then run in multiple modes: strict and lenient. Robustness and testing If you have ever implemented a specification, you have probably seen a section like this:…
This is a quick tutorial on how to turn of the nix flake registry. What is the nix flake registry? The nix flake registry is a per-machine or per-user mapping of names to flake identifiers. For example, nixpkgs represents git://github.com/NixOS/nixpkgs . You can list yours using nix registry list . It is what lets you write nix run nixpkgs#firefox instead of github:NixOS/nixpkgs#firefox . It also…
This blogpost explains and argues the claim that Ad-hoc polymorphism (Type-classes in Haskell/Scala/Purescript, Traits in Rust, Interfaces in Go/Java) makes code less type-safe. In other words: ad-hoc polymorphism makes it so that sometimes, after a refactor, code that is wrong and would not type-check without it, now still type-checks. Time to write a blog post I've been digging into Rust for a…
All CS SYD services ( Intray , Tickler , Smos , Social Dance Today , ...) were down on 2023-08-08 between 12:30 and 18:00 Zürich time. This is a postmortem of the outage. Full story Symptoms Around 12:30, I get Intray notifications saying that my services are unreachable. I browse to https://cs-syd.eu and don't get a response. I try to ssh into the machine, and the command hangs. Because I had a…
Smos has been the centerpiece of my self-management for years now, but most of my clients have not been software engineers. Smos still fits a software development workflow very well, so I figured I would describe an example workflow here. Jumping into a codebase to make some fixes can be more stressful than necessary. You find things that could be refactored, you might find bugs, missing tests, or…
This post announces the new ical Haskell library for implementing with RFC 5545: Internet Calendaring and Scheduling . RFC 5545 is a widely used specification for calendar data exchange on the internet. It defines a data format for representing calendar events, such as appointments, meetings, and reminders. Historical perspective In order to build Smos' smos-calendar-import tool to view your…
This post announces the new profiling mode for sydtest with which you can find out why your test suite is slow. One of the test suites for Social Dance Today contains 341 test. Each of those may run purely, use a clean database, or spin up a real server with a clean database. Yes sydtest shows the timing already for each test, colour coded, even, but it can still be difficult to find out which…
This is the story of a space leak in the Social Dance Today server and how we fixed it. Symptoms A few months ago, I suddenly got a bunch of alarm emails saying that my site (the one you're reading this on) had gone down. I was about to teach our dance class at the time, so I quickly logged into the AWS console and restarted my server in the hope that that would fix it. I figured that if that…
A review of my 2022: CTO work, dancing across continents, and building systems. Highlights I worked as a CTO and led a team of teams of engineers. I traveled to 8 countries and danced in every one of them, as well as on a fourth continent! I built a new workstation and backup system. I made enough money teaching dance to pay for laundry this year. I grew Social Dance Today to thousands of monthly…
This post announces Dekking , a next-generation code coverage tool for Haskell. In the short-term, Dekking unblocked me by easily letting me make multi-package code coverage reports where I previously failed to do so. In the medium-to-long term, Dekking intends to replace HPC . Why not "just" use HPC? Multi-package code coverage reports Most of my project consist of multiple packages. The smos…
Programming usually does not happen by writing a program from start to finish, deploying it, and then never touching it again because it is done. Instead, programming happens in incremental cycles: Notice space for improvement. Make changes. Get feedback on those changes. Repeat. I will call these cycles the feedback loop. Noticing space for improvement is rarely a difficult or lengthy task.…
This post announces feedback , a tool to help you and your team set up and maintain feedback loops. The feedback tool is available on GitHub and on Hackage . I have written about feedback loops before, and in fact referring to that blogpost is what gave me the idea for this tool. The feedback tool is a manifestation of my strong opinion that one should start any programming task by setting up a…
Dealing with money in software is difficult and dangerous. This post contains an overview of the problems you will run into eventually when writing software that deals with money. It describes potential representations, relevant trade-offs, and recommends ways of correctly implementing common operations. The post is prescriptive, so that you can use it to write your own library for dealing with…
This post announces the new version 0.2.0.0 of the safe-coloured-text library. The safe-coloured-text library lets you safely output coloured text to a terminal. The idea for version 0.2.0.0 came from a very smart and annoyingly sensible comment on reddit . The first ( 0.1.0.0 ) version made the now-considered-erroneous decision to require the user to use UTF8. The newest ( 0.2.0.0 ) version…
This is the fifth year that I am writing one of these. The big conclusion, this year, is that my life is bloody amazing. I have so much to be thankful for. Highlights Work My work has become much more varied this year. I started working as an independent consultant, taking care of anything that is necessary to produce software that works. This is everything from programming, to DevOps, to hardcore…
This post announces the latest 1.0.0.0 release of genvalidity and all its companion packages . It re-introduces validity-based testing and elaborates on the choices that went into the new release. Quick intro to validity-based testing If you've ever done any property testing, you will know that writing generators, shrinking functions, and properties is an expensive process. Validity-based testing…
This post announces the new autodocodec library and its companions. The library was inspired by aeson s vulnerability , the response to my rules for sustainable Haskell and the excellently documented tomland library by Kowainik . It is already used in production at CS-SYD and is ready for others to try. Inspiration When the aeson s vulnerability blog post came out, I was reminded of Chris Done's…
This post outlines different types and levels of testing that you can add to your testing portfolio. The central assumption is that the marginal effectiveness of tests drops as you add more similar tests to your portfolio. So to get the most bang for your buck, you want to add as many different types of tests to your portfolio. Purpose of a testing portfolio To write code that works, you want to…
Test pollution is a major barrier to efficient and approachable testing practices. Luckily it is much easier to solve than we usually estimate. What is test pollution A test is considered polluting if there is a difference in the likelihood that it or other tests pass, if the test is not run, run in parallel, or run in a different order. That's quite the mouthful, so let's look at more specific…
Mocking is a very common testing mechanism, and it is a bad idea . This post details why you should not use mocking, and why and how you should write integration tests instead. TL;DR: Mocking provides false confidence by hiding real failures. Disclaimer: This post uses example code in Haskell, but the same principles apply in other programming languages. What is mocking Writing a test using a mock…
This blogpost describes a DoS vulnerability in Haskell's aeson package. We have followed appropriate procedure for responsible disclosure but the problem was not fixed, so now we are releasing this to the public in the hope that it may still be fixed afterall. Disclaimer: This story is the result of a team effort at FP Complete in 2018. I have received explicit written permission to post it here.…
This post describes "the undefined trick" for introducing compile errors when the number of fields in a record is changed, in Haskell. Example situation: HTML Description Suppose you are working on SEO for a website. The website displays blog posts, one per page. You're tasked with writing the code that generates the <meta name="description"> tag that helps determine what your blog post will look…
Smos has recently gotten a new companion tool called smos-github , which allows for easier integration of your self-management workflow with GitHub. In this post I will propose a sample workflow for developers to keep track of, and follow up on, the issues and pull requests that they are involved in. We assume a basic working knowledge of how to implement GTD in Smos. Managing software projects…
Having set up CI for dozens of repositories, Nix and otherwise, I think I've stumbled upon some best practices. The following describes a pattern that includes all those practices. In a nutshell Have a ci.nix file in the root of your repository that evaluates to an attribute set. Have developers run nix-build ci.nix before they submit a pull request. Run nix-build ci.nix on CI as your CI…
This post announces the new safe-coloured-text library. The prompt to make this library was that the maintainer of the rainbow package didn't want to get rid of the lens dependency to decrease its dependency footprint . I learnt a lot while writing this library, and it has produced some of the prettiest output that I have ever seen in my terminal. It turns out that most "coloured text" libraries…
The very first thing I do when working on a programming task is to set up a feedback loop. The idea of the feedback loop is to be able answer the question "am I done?" as quickly as possible. The shorter this loop is, the quicker you can iterate. I have been making quite a few changes to this website to allow for a quicker feedback loop. The first was to only bake the contents into the binary in…
This is the fourth year that I am writing one of these. I was really not looking forward to it this year. Highlights I didn't die. I didn't get very sick. I was self-employed for all of 2020, working remotely for multiple clients as a technical leader and engineering manager. I started teaching self-management professionally I discovered how much I enjoy ring training I wrote two articles on…
After experimenting with Haskell templates for a few weeks, I am excited to officially launch my Haskell Templates . A few people asked to hear about what goes into a project like this, so in this post I would like to tell you about the project's history. Phase 0: The templates idea I started this project because I saw templates for front-ends in many places, most notably for Wordpress. I asked…
Earlier this month, I wrote a post about validating the idea of selling Haskell templates. In the time since then, I have made and sold multiple copies of the first template at https://template.cs-syd.eu. Today I am releasing the second template: A command-line tool . The template features everything you need for a command-line tool project anyway: Haskell code for a multi-command CLI tool…
I have had the idea of selling Haskell templates for a while now, and I am now getting around to validating this idea. I have also been trying to learn more about indie-hacking so here goes my first proper attempt. Please have a look at my quick landing page, here: Landing page and fill in my little feedback form here: Feedback form Please share this post so that I can gather more data.
Hacktoberfest is happening again in 2020 and CS SYD will be participating again. Contributions are very welcome, and do not need to be pre-defined. Below are some good issues to get started with. Documentation in particular is very welcome, and can be a great way to get started with any given project. Last year we had some lovely contributions , so I will do my best to help keep up this good work.…
I gave a talk about practical property testing at FP in the city 2020 online on 2020-09-10. The talk was recorded and can be found online: Slides are available on GitHub Feedback is always welcome via email.