Plurrrr

week 11, 2023

Go slow to move fast

There’s isn’t a universal answer to the best way to balance development velocity against technical debt. Thinking of debt as something taken on intentionally by a team to increase their short-term velocity at the expense of future work is an easy to apply strategy that has many benefits to engineering teams while also simplifying the concept for less technical individuals. By measuring accrued debt against long-term baselines and ceilings, engineering managers can get a feel for how much this debt is impacting their teams, and this data can be used to aid in prioritization decisions and high-level discussions with stakeholders.

If your goal to to increase your teams' overall development velocity in the long term, remember that you may want to slow down so that you can move fast.

Source: Go slow to move fast, an article by Jordan Kaye.

A different approach to fuzzy finding

After growing frustrated by various fuzzy finders not being as accurate as I expected, I designed a new fuzzy finder called zf. I have mentioned zf in passing many times, but until now I haven’t taken the time to write about it in detail. In short, zf is a new terminal fuzzy finder with a ranking algorithm designed specifically for filtering filepaths. It has been rewarding to develop and use, and perhaps you will enjoy it too!

Source: A different approach to fuzzy finding, an article by Nathan Craddock.

A Comprehensive Guide to Structured Logging in Go

Structured logging involves producing log records in a well-defined format (usually JSON), which adds a level of organization and consistency to application logs, making them easier to process. Such log records are composed of key-value pairs that capture relevant contextual information about the event being logged, such as the severity level, timestamp, source code location, user ID, or any other relevant metadata.

This article will delve deep into the world of structured logging in Go, with a specific focus on recently accepted slog proposal which aims to bring high performance structured logging with levels to the standard library.

Source: A Comprehensive Guide to Structured Logging in Go.

The power of single-method interfaces in Go

The other day I was pondering on the prevalence of single-method interfaces (SMI) in Go, and what makes them so effective and useful. SMIs have proven to be a very successful software modeling tool for Go programmers, and you find them all over Go code-bases.

I tried to think about the fundamentals, which brought me to some of the earliest roots of our trade: functional programming and higher-order functions (HOF). I discussed some examples of applying higher-order functions in Go recently.

This post will describe how SMIs are a more general and powerful technique than HOFs. It makes the following claims:

  1. SMIs can do whatever HOFs can
  2. SMIs are more general
  3. SMIs are somewhat more verbose for simple cases

Source: The power of single-method interfaces in Go, an article by Eli Bendersky.

Oblivion (2013)

A veteran assigned to extract Earth's remaining resources begins to question what he knows about his mission and himself.

In the evening Alice, Esme, and I watched Oblivion. I had seen the movie before, years ago. I liked the movie and give it a 7 out of 10.

The friendship between Haskell and C

If ever there were two programming languages said to be at odds with one another, it might be Haskell and C. But this is not so true as it seems; they can play quite nicely with one another. Haskell’s foreign function interface lets us write Haskell code that uses libraries of other languages — notably, C.

As a brief introduction to how Haskell FFI works, I’ll be talking about my memfd package, which is available on Hackage.

Source: The friendship between Haskell and C, an article by Chris Martin.

Temporary lifetimes

Rust’s rules on temporary lifetimes often work well but have some sharp edges. The 2024 edition offers us a chance to adjust these rules. Since those adjustments change the times when destructors run, they must be done over an edition.

Source: Temporary lifetimes, an article by Niko Matsakis.

Functors

A functor between two categories (let’s call them A and B) consists of two mappings - a mapping that maps each object in A to an object in B and a mapping that maps each morphism between any objects in A to a morphism between objects in B, in a way that preserves the structure of the category.

Source: Category Theory Illustrated - Functors.

Analyzing multi-gigabyte JSON files locally

I’ve had the pleasure of having had to analyse multi-gigabyte JSON dumps in a project context recently. JSON itself is actually a rather pleasant format to consume, as it’s human-readable and there is a lot of tooling available for it. JQ allows expressing sophisticated processing steps in a single command line, and Jupyter with Python and Pandas allow easy interactive analysis to quickly find what you’re looking for.

Source: Analyzing multi-gigabyte JSON files locally, an article by Jan Seeger.

Rust's Two Kinds of 'Assert' Make for Better Code

Daniel Lemire's recent post "runtime asserts are not free" looks at the run-time cost of assert statements in C and shows that a simple assert in a frequently executed loop can cause significant overhead.

My own opinion on assertions has shifted over the years, from "I don't see the point" to "use them sparingly" to "use them as much as possible". That last shift is largely due to Rust having two kinds of "assert" statement – assert and debug_assert – which has allowed me to accurately express two different kinds of assertions, largely freeing me from performance worries. If you come from a language that only has one kind of assert statement, this distinction can seem pointless, so in this post I want to briefly explain why it helped shift my thinking.

Source: Rust's Two Kinds of 'Assert' Make for Better Code, an article by Laurence Tratt.

Quick VMs with NixOS

Very often during development, it is useful to run your code in a scenario that is as near to a final deployment as possible, but not in some cloud environment where it’s hard to change specific parts without going through the full CI/CD chain. I find it very useful to quickly build, run, iterate, rebuild, and rerun VMs with NixOS Linux on my development machines. This week I demonstrate this aspect of my workflow with NixOS.

Source: Quick VMs with NixOS, an article by Jacek Galowicz.

Stop Using Custom Web Fonts

I recently read an excellent post by Manu Moreale titled A rant on web font licenses. I highly recommend you give it a read (it's relatively short) since Manu makes a solid argument against existing font licenses. After reading, I found myself thinking about it throughout the rest of the day.

I was trying to understand how we ended up in a situation where web/UI designers (myself included) have started to insist on using proprietary, custom web fonts. Do any users actively benefit from custom web fonts? Are there any useful and measurable goals achieved by including them? Do end-users actually care about a website's typeface?

For the most part, I believe the answer to all those questions is: not really.

Source: Stop Using Custom Web Fonts, an article by Bradley Taunt.

In Defense of Crusty Old Swiss Army Knives

I’m a fan of crusty old knives.

There’s a cold familiarity to them; you know what they’re good for and what they’re not, and despite their age, they remain largely the same as how you left them. In software, there aren’t a lot of tools that are allowed to get old. I feel like the default state is just a drop-off into obscurity.

But Django got old! Its twentieth birthday is almost here. I suppose that means Django has entered adulthood now, though 20ish years in software probably puts it more toward seniorhood than anything. When I stare at a CRUD-style use case, Django remains my default impulse. With the rise of stripped-down JS frameworks like HTMX, I thought it’d be exciting to pull out the crusty knives, sprinkle in some new JS goodness and explore the landscape. What follows in this article are my thoughts and lessons along the way. Enjoy!

Source: In Defense of Crusty Old Swiss Army Knives, an article by Zach Goldstein.

Announcing FawltyDeps - a dependency checker for your Python code

It is a truth universally acknowledged that the Python packaging ecosystem is in need of a good dependency checker.

In the least, it’s our hope to convince you that Tweag’s new dependency checker, FawltyDeps, can help you maintain an environment that is minimal and reproducible for your Python project, by ensuring that required dependencies are explicitly declared and detecting unused dependencies.

If you work with Python, and care about keeping your projects lean and repeatable, then this is for you.

Source: Announcing FawltyDeps - a dependency checker for your Python code, an article by Johan Herland, Nour El Mawass, Maria Knorps, and Vince Reuter.

Emitting Safer Rust with C2Rust

In this post, we will discuss recent results from Immunant and Galois in extending C2Rust to emit memory-safe Rust in certain cases. With this work we aim to shift a meaningful part of the translation burden from the human to the machine. Up until now, C2Rust has only been able to translate C to unsafe Rust that is no safer than the original input C code. Although this provides a starting point for manual refactoring into idiomatic and safe Rust, this work had to be done by the human. By using a combination of static and dynamic analysis, the current in-development version of C2Rust can now perform some of the lifting to safe Rust automatically. This post describes how this analysis works and how we are using it to make it easier to translate unsafe C programs into memory-safe Rust.

Source: Emitting Safer Rust with C2Rust, an article by Per Larsen and Eddy Westbrook.

Tour of a HTTP request in Rust

When we talk about a web service, we, more often than not, mean deployed code which listens on a certain IP address and port and responds to HTTP messages. There are many steps involved for two parties to be able to communicate with each other. Application developers are mainly confronted with two pieces of this process: TCP and HTTP.

Source: Tour of a HTTP request in Rust, an article by Bastian Gruber.

Policy on util packages

Ah util, the ubiquitous fixture of practically every project since the invention of code.

I spent my early years programming expecting a util package in every project, oftentimes being the one to create it myself. It wasn’t until my third job out of school that I ran into someone who had an allergic reaction to the addition of one and argued strongly against it.

Source: Policy on util packages.

The Killing God

They are coming.

The kingdoms of Belleger and Amika had been fighting for generations. But then they learned of a terrible threat moving through them to destroy the Last Repository, an immense hidden library. To face this greater enemy, King Bifalt of Belleger and Queen Estie of Amika allied their lands and prepared for war.

They are at the door.

Now the time of preparation is over. Black ships and sorcery test the cannon that defend the Bay of Lights. Treachery and betrayal threaten the kingdoms. The priests of the Great God Rile sow dissent. And Estie rides for the Last Repository, desperate to enlist the help of their Magisters-and to understand the nature of her own magical gift.

They are here.

Bifalt hates sorcery as much as he loves Estie, and the discovery that she could become a Magister shatters him. But he must rally and fight. Belleger and Amika are all that stand between the Great God's forces and his ultimate goal: the destruction of the Last Repository and its treasure of knowledge.

In the evening I started in The Killing God, the 3rd book in The Great God's War trilogy by Stephen Donaldson.