A Dictionary of Single-Letter Variable Names

Posted on October 12, 2024 by Jack Kelly
Tags: haskell, coding

Haskell’s expressive type system means that type signatures can carry a lot of information. Haskell’s polymorphism means that you sometimes write functions that work across an enormous range of types, and are left wondering “what do I actually call my variables?”. It is often the case that there’s nothing to say beyond “this variable is a Functor”, or “this variable is a monadic action”, and so a single-letter variable name is appropriate. An unofficial and largely undocumented convention has emerged around these variable names, and so I wanted to write them all down in one place.

It should go without saying that single-letter variable names are not always the answer. Like point-free style, it sometimes obscures more than it helps and people get carried away with it. But when you have a highly polymorphic function and no good words to use, choosing the right letter can convey a surprising amount of meaning.

This dictionary is not and cannot be exhaustive. Variable naming often relies on context to convey information, and shorter variable names should only be used when they make sense in context. That context could be:

With the warnings out of the way, the dictionary is after the jump. The bulk of the dictionary documents type variables, where overly long variable names can blow out complicated type signatures. Important value-level variable names are also documented, and are explicitly labelled as such.

Read more...

Travel Tip: USB-C Desktop Chargers

Posted on October 6, 2024 by Jack Kelly
Tags: travel

I have travelled a lot this year, and after yet another trip where I lugged too many things around, I’ve been thinking about ways to cut back. The classic guide for this is onebag.com, which covers a very interesting mix of techniques and some carefully-chosen lightweight gear that will take you to the farthest corners of the map. Perma-nomad Vitalik Buterin has his own take on living out of a 40L backpack; one of his key points is to run everything you can off of USB-C. The benefits should be obvious: you cut down the number of charging cables you need to carry and your power bank can recharge any of your devices. While I’m a bit of a luddite, I can see a lot of people travelling with at least a laptop and phone, and possibly also a tablet, earbuds, and/or a smartwatch, all of which need power.

Vitalik’s guide mentions a USB-C “wall wart” charger that he uses to power his stuff. I disagree with this choice, at least for international travel: I think you want a desktop USB-C charger that takes an IEC C7 (“figure 8”) cable.

I’m not aware of any good articles that spell out the “desktop charger + replaceable cable” trick and how to actually find a suitable one, so a full explanation, research procedure, and some tentative recommendations are spelled out in laborious detail after the jump.

Read more...

I'm Funding Ladybird Because I Can't Fund Firefox

Posted on July 6, 2024 by Jack Kelly
Tags: rants, web

I’ve been meaning to write this one for a while, but the announcement of the Ladybird Browser Initiative makes now a particularly good time.

TL;DR: Chrome is eating the web. I have wanted to help fund a serious alternative browser for quite some time, and while Firefox remains the largest potential alternative, Mozilla has never let me. Since I can’t fund Firefox, I’m going to show there’s money in user-funded web browsers by funding Ladybird instead. You should too.

Read more...

Why `streaming` Is My Favourite Haskell Streaming Library

Posted on April 13, 2024 by Jack Kelly
Tags: coding, haskell

It’s really easy to misuse lazy I/O (e.g., hGetContents) in nontrivial Haskell programs. You can accidentally close a Handle before the computation which reads from it has been forced, and it’s hard to predict exactly when data will be produced or consumed by IO actions. Streaming libraries in Haskell avoid these problems by explicitly interleaving the yielding of data and execution of effects, as well as helping control the memory usage of a program by limiting the amount of data “in flight”.

A number of veteran Haskellers have built streaming libraries, and off the top of my head I’m aware of conduit, io-streams, iteratee, machines, pipes, streaming, and streamly. Of those, I think conduit, pipes, streaming, and streamly are the most commonly used ones today. It can be hard to know which library to choose when there’s so many options, so here is my heuristic:

  1. If you’re doing simple streaming (e.g., from a network connection straight into a file), use whatever your library uses (usually conduit); or
  2. If you’re doing anything more complicated, or you’re doing greenfield work, use streaming.

I’ll explain why after the jump.

Read more...

Which Build Tool For A Bootstrappable Project?

Posted on April 1, 2024 by Jack Kelly
Tags: coding, c, autotools, meson, cmake

I have a nascent side project which is intended to participate in a bootstrap chain. This means it shouldn’t depend on too many things, that the transitive closure of its build dependencies must also be small, and at no point in the process should any build depend on an opaque binary blob.

Choices on the language side are pretty constrained. Zig is currently not a candidate (despite the language itself being rather promising), because it has removed its C++-based bootstrap in favour of keeping a WASM-based build of a previous compiler version. It’s great that their compiler output is reproducible — Zig-built-by-Zig is byte-for-byte identical with Zig-built-via-WASM — but for now, it’s not truly bootstrappable. (Andrew Kelley says he hopes someone writes a Zig compiler in C when Zig stabilises. I sincerely hope this happens.)

Rust is right out, for reasons described in the Zig article:

Use a prior build of the compiler - This is the approach taken by Rust as well as many other languages.

One big downside is losing the ability to build any commit from source without meta-complexity creeping in. For example, let’s say that you are trying to do git bisect. At some point, git checks out an older commit, but the script fails to build from source because the binary that is being used to build the compiler is now the wrong version. Sure, this can be addressed, but this introduces unwanted complexity that contributors would rather not deal with.

Additionally, building the compiler is limited by what targets prior binaries are available for. For example, if there is not a riscv64 build of the compiler available, then you can’t build from source on riscv64 hardware.

The bottom line here is that it does not adequately support the use case of being able to build any commit on any system.

As far as I can see, the best choice for writing bootstrap-related software in 2024 is still C99, with as few dependencies as possible. Any (hopefully few) necessary dependencies should also be bootstrappable, written in C99 and ideally provide pkg-config-style .pc files to describe the necessary compiler/linker flags. But at least there are several C compilers as well as several implementations of pkg-config (the FreeDesktop one, pkgconf, u-config, etc.).

Since we are compiling C, what should we use for the build system? Autotools is under scrutiny again in the wake of the xz-utils compromise, as code to trigger the payload was smuggled into the dist tarball as “autotools junk” that nobody looks at. Should bootstrappable projects still use autotools, or is there something better in 2024?

Read more...
All Posts | RSS | Atom
Copyright © 2024 Jack Kelly
Site generated by Hakyll (source)