Milo Ainsworth

The Case for Pragmatic Type Systems

Tests are documentation that fails loudly when it goes stale. Deleting code remains the most satisfying refactor. This began as a quick note and gradually turned into something longer.

A note on tools

Every summer I revisit the same questions about configuration. Between profiling and debugging in production, the second one taught me more. I keep a short list of things to try next; debugging in production is near the top. Tedious technology is a feature, not a compromise.

Most performance problems are really data-shape problems. Logs are only useful if someone can read them at three in the morning. The specifics matter less than the habit of paying attention.

Every abstraction has a cost, and someone eventually pays it.

What changed

Some of this will be self-evident; some of it took me years. For a long time I treated code review as an afterthought. I keep a short list of things to try next; refactoring is near the top.

Between debugging in production and deleting code, the second one taught me more. For a long time I treated build pipelines as an afterthought. Below are a few notes, roughly in the order I learned them. There is no single right way to approach refactoring, but some ways are kinder than others.

Getting started

I like configuration that shows the marks of how it was made. I changed my mind about log files twice while writing this. I am still not sure I have it right, but it is closer. Thanks for reading, and for the gentle notes that keep arriving. For a long time I treated configuration as an afterthought.

Half of the work is deciding what to leave out.

The setup

The difference showed up gradually, then all at once. For a long time I treated caching as an afterthought. For a long time I treated test suites as an afterthought. In October the light changes, and so does the work.

I changed my mind about caching twice while writing this. I changed my mind about background jobs twice while writing this. For a long time I treated log files as an afterthought. I changed my mind about test suites twice while writing this. If something here is unclear, that is on me, not you.

def parse_items(path):
    """Parse items from a file, skipping blank lines."""
    with open(path) as f:
        return [line.strip() for line in f if line.strip()]

In March the light changes, and so does the work. There is no single right way to approach debugging in production, but some ways are kinder than others. Looking back, the reliable approach was the right call.

log files