RSSAmplifier

Blog

Andy Balaam's Blog

Coding in Rust and others; making coding videos.

artificialworlds.netRSS feed ↗614 posts

Latest posts

LLMs produce plausible noise

I know everyone and their dog is writing about LLMs, and since I refuse to use them you probably shouldn't listen to me, but I have recently solidified some of my thinking about them and thought it might be useful to share. None of this makes any difference to the disastrous ethical position of LLMs, but it has helped me understand them a bit more, and fear them a bit less. Background: the…

Parsing SGF files for fun

SGF files describe a board game like Go, including all the possible variations someone wants to talk about. Let's write Rust to parse one of these files! They look something like this: (;FF[4]GM[1]SZ[19];B[aa];W[bb];B[cc];W[dd];B[ad];W[bd]) Follow me on mastodon: @andybalaam@mastodon.social

A full (slow) solution to the Billion Row Challenge

We've been picking off small sub-tasks of the Billion Row Challenge, which asks us to summarise a large amount of data as quickly as we can. This time we complete the whole challenge, but in a slow way, to make sure we understand it. In future videos we will attack the last remaining sub-tasks, which concern how to collect together the information (probably in a hashmap) and print a summary.…

The billion row challenge: do we have a bug?

A couple of people contacted me with feedback about the SIMD implementation we used to find newlines in the billion-row file. One suggested a possible bug (shock!) and one suggested a way that might be more efficient. We'll take a look at both, obviously starting by writing a test that checks for the bug. After the stream I made another attempt at using the information about all newlines in a…

Writing a bit-wise iterator (with Jez!) for our gunzip implementation

More Jez+Andy coding, working on our gunzip clone. Jez figured out we need to iterate bit by bit through the input, so we write a Biterator to do that. The code is at https://codeberg.org/andybalaam/ggunzip . Read Jez's blog at https://www.jezuk.co.uk/ Follow Jez on mastodon: @jezhiggins@mastodon.me.uk Follow me on mastodon: @andybalaam@mastodon.social

Keep the faith

This is mainly a message to myself. I have spent the last few weeks feeling more and more depressed about "the tech industry". I am sad that social media companies are manipulating us, making us angry and ignorant. I am sad that AI is becoming more pervasive when I feel it is fundamentally unethical . I am worried that I may lose my job if I don't use AI, or feel pressured to use it. I am…

Implementing gunzip from scratch in Rust

Jez and Andy get together for crazy programming hijinks, trying to figure out from scratch how gzip compressions works, starting by making a valid minimal gzipped file, then trying to unzip it. Read Jez's blog at https://www.jezuk.co.uk/ Read my blog at https://artificialworlds.net/blog Follow Jez on mastodon: @jezhiggins@mastodon.me.uk Follow me on mastodon:…

Jez returns for programming language chat!

Veteran super-coder Jez is back, and claims he has "finished" implementing Cell, Andy's toy language, in Rust. Jez and Andy basically gossip a bit, about code type stuff. Read Jez's blog at https://www.jezuk.co.uk/ Read my blog at https://artificialworlds.net/blog Follow Jez on mastodon: @jezhiggins@mastodon.me.uk Follow me on mastodon:…

Announcing Changelog Builder - a towncrier clone for building changelogs

I really enjoy re-implementing things that already exist. Sometimes it's just out of interest, sometimes it's to make it faster, or work in a different way, or improve the code quality, but I love having that concrete expectation of what the code does to work from. So, when a colleague suggested we might use towncrier to handle our release notes, but I knew its Python implementation…

Using anyhow to handle errors in my Rust changelog builder

Let's fix our messy error handling in our Rust towncrier clone by using the anyhow library and adding context() calls to describe what went wrong. Can we match the output of towncrier in different circumstances? Do we actually want to match it exactly, or can we do better? You can find the code at https://codeberg.org/andybalaam/changelog-builder Follow me on mastodon:…

A simpler blog comment system

Since I made this blog statically-generated using Zola I've been using Remark42 as my comment system. I wanted something self-hosted and simple, and it worked. These days I get a comment every couple of months, and about half of them are spam. Remark42 seemed to forget who I was each time, so deleting the spam involved me remembering where Remark42 was deployed, editing and re-uploading a…

Building a Rust commandline tool: a towncrier clone

Enthusiastically embracing test-driven development as always, we attempt to write a minimal clone of a useful tool, towncrier, which allows us to build changelogs out of individual "newsfragment" files. By the end we have the outline of a decent solution that passes our first and only testcase! You can find the code at https://codeberg.org/andybalaam/changelog-builder Follow me…

The billion row challenge: splitting lines using SIMD in Rust

I was scared to do it, but it was actually fine! This time we look at the quickest way to split up massive text files into separate lines, first by implementing our own zero-copy version of BufReader::lines and later using SIMD, which allows us to process 64 bytes simultaneously, using a single CPU instruction! I'm pretty sure this is the first time we've ventured into nightly Rust on…

Rust: reading very large files for the billion row challenge

Checking out whether memmap can help us read very large files as fast as possible, and wondering how wc manages to be so fast. This is the next bit of the Billion Row Challenge, and probably the closest part to black magic. Follow me on mastodon: @andybalaam@mastodon.social

Parsing whole lines of the Billion Row Challenge

Excitingly, our temperature parser can be trivially extended to find the start of the temperature, so we can use it to parse the whole line! Follow me on mastodon: @andybalaam@mastodon.social

Improving our billion-row parsers and benchmarks

Improving the benchmarks of our Billion Row Challenge, and playing with some improved implementations. Follow me on mastodon: @andybalaam@mastodon.social

Making our own String type in Rust

Implementing our own versions of standard types can help us understand how they work a bit better. This time we'll make a new string type called AsciiString, and make it handle all its memory itself. Lots of unsafe, and probably lots of bugs! Follow me on mastodon: @andybalaam@mastodon.social

Writing a Snake game in Rust/WASM

Last time we did the hard work, so this time we can focus directly on writing a fun game of Snake using pure Rust, running in a browser canvas via WASM. Follow me on mastodon: @andybalaam@mastodon.social

Talking to localhost from inside an Android emulator

If you're developing an Android application that talks to a server, you may well want to run the server locally and talk to it from your Android emulator. If you point at localhost , this means the Android device itself, not the server running on your computer. There is various information about how to make this work online, but the only reliable way I have found is to run a command like this…

Rust: compiling to WASM to make a browser-based game using canvas

I love writing Rust, and I love writing simple games, so let's combine the two by showing how to make a tiny game framework with these properties: 99% of the code is Rust, compiled to WASM the game runs in any non-ancient Web browser the screen drawing is on a zoomed-in canvas so we can make pixelated retro-games Set up Before we start, we need to install: Rust , and wasm-pack Note: there is…

Billion row challenge: parsing temperatures fast(ish)

I watched Jon Gjengset taking on the one billion row challenge and got interested in one small corner of it: parsing temperatures, and in particular parsing temperatures in a "branchless" style - with no if statements - to help the CPU run the code as fast as possible. In the end, the results were surprising. After the stream I added a version of Jon's parse_temperature to the comparison. His…

Rust: building arbitrary precision integers (badly)

I thought it might be quite straightforward to show the basics of how we could design a "BigInt" type of struct. It turns out it was more involved than I thought it would be, but we got a little way into it. Maybe we can continue in a later video? Follow me on mastodon: @andybalaam@mastodon.social Comments Tiger12506 2026-07-21 Starting with base-256 u8 instead of base-10 BCD is quite the flex.

Rust: how to return a closure from a function, and what are closures anyway?

Sometimes we want to return a closure from a function, and sometimes that doesn't work the way we might expect. This will lead us on to how we should think of closures: they're not really like functions so much as automatically-generated structs with types we are not allowed to name. And all closures have different types, even if they're identical...? Follow me on mastodon:…

FizzBuzz 2: FizzBuzz Harder

I implemented FizzBuzz before, but in retrospect I don't like what I did. I especially don't like my tests. So let's try to do better, and talk about why it's better. Follow me on mastodon: @andybalaam@mastodon.social

Why I don't use AI

(Balaam, A.J. (2025). In F. Buontempo, editor, Overload 190 (2025) .) I choose to avoid using "AI" (by which I mean Large Language Models 1 ). Here's why: they have a devastating environmental impact, they are trained by exploiting and traumatising millions of low-paid workers, they produce biased and dangerously incorrect results, and they unfairly use people's creative work.…

Converting a string to an int in Rust (for no reason)

How about a little light relief? Let's convert a string to an int in Rust. Follow me on mastodon: @andybalaam@mastodon.social

Why I don't use AI (expanded)

Soon after I wrote Why I don't use AI , I researched and submitted a significantly longer version to ACCU's Overload journal. It has now been published! You can read it here: Why I don't use AI (Overload) . It contains references to a lot more sources, and expands on my reasoning. Update: the original was moved behind a paywall, so here is the full article hosted here: Why I…

Resizing and moving an encrypted LVM volume

I use a LUKS-encrypted LVM setup for my laptop. Within the encrypted volume I have partitions for / and /home and I guessed the sizes wrong, so I needed to change them. I did various reading, and even resized some filesystems and partitions, before I discovered the answer that made it all very easy for me. Reboot into an Ubuntu live USB, do sudo apt install partitionmanager and then…

Implementing FizzBuzz in Rust (for no reason)

Things getting you down? Let's implement FizzBuzz. It should be low stress because it's not a difficult task, but maybe we can think about some nice ways to make it work. Follow me on mastodon: @andybalaam@mastodon.social

Reversing a string in Rust (for no reason)

Feeling slightly exhausted by the world? Let's reverse a string in Rust in a needlessly complicated way. I was expecting to make a tiny simple video and ended up going further into unsafe than I ever have before, which was an unexpected treat. Let me know what I got wrong! Follow me on mastodon: @andybalaam@mastodon.social

Mini-rust in Rust 050: Parsing function definitions

To make real programs, we will need functions. We'll start off by allowing you to define functions that take no arguments. You can find the source code at codeberg.org/andybalaam/milk and more of my stuff at artificialworlds.net Comments at0m 2026-05-18 Looking forward to more episodes! Andy Balaam 2026-05-20 Thanks at0m! I'm not sure many other people were keen, so I'm…

Why do I have 2 passwords? How to talk about encryption in Matrix

Most modern software applications give total trust to the service provider. End-to-end encrypted (E2EE) services are different: the service provider is a gateway, and the real trust is with other people. This is unfamiliar, and can make using E2EE confusing. When you add in federation (meaning lots of different service providers) and a diverse set of client apps, trying to make Matrix's…

Invisible Crypto: can Matrix be both secure and easy to use?

The Invisible Crypto initiative intends to make Matrix easier to use by ensuring that encrypted messaging is secure by default, and the user is not bothered by irrelevant information. In this talk we will give a status update, hopefully explaining why crypto needed to become slightly more visible on the journey towards making it disappear. We'll go into some detail about what we've done…

Mini-rust in Rust 049: Lexing an empty function

The next big thing we need to be able to do is define functions. Let's start by lexing the fn keyword and brackets: we're going to need both of those. You can find the source code at codeberg.org/andybalaam/milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 048: Handling variable scope

Variables should be defined inside their curly braces and not elsewhere, and it should be fine to "shadow" variables by defining new ones inside a smaller scope. You can find the source code at codeberg.org/andybalaam/milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 047: Updating types as we get more information

If we know that y is an f64 , when we see x *= y , we can guess that x is an f64 too. You can find the source code at codeberg.org/andybalaam/milk and more of my stuff at artificialworlds.net

Jez and Andy write a Parser

My friend Jez is back, and we make a start on a parser for the Cell language (in Rust, of course). You can find Jez at jezuk.co.uk and follow him at @jezhiggins@mastodon.me.uk . Soon after we finished recording, Jez reported to me that he&#x27;d got it passing all tests, and provided this code snippet: fn next_node(&mut self, prev: Option<AST>) -> Option<AST> { match self.next_token() {…

Jez learns Rust by writing a Lexer

My friend Jez joins us and we talk about his new implementation of my Cell programming language in Rust, which is his first from-scratch Rust project. You can find Jez at jezuk.co.uk and follow him at @jezhiggins@mastodon.me.uk .

Mini-rust in Rust 046: Type-checking mutations

When we see x *= 1.3 we need to check that x is a float - otherwise this is a compile error. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 045: Combining two types when we add things

We had a weird hack in place to handle the type of an expression like x + 3 but now we can do better. Let&#x27;s do it! You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Why I don&#x27;t use AI

I choose to avoid using "AI" (by which I mean Large Language Models ). Here&#x27;s why: They have a devastating environmental impact . 1 2 They are trained by exploiting and traumatising millions of low-paid workers . 3 4 They produce biased and dangerously incorrect results . 5 6 7 They unfairly use people&#x27;s creative work . 8 9 There are many other reasons, including that they don&#x27;t do…

Mini-rust in Rust 044: Finding the type of a symbol

If we write let x: i32 = 3; then we should know that x is an i32 , right? Let&#x27;s make it so! You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 043: Expressions on the left of operators

The final (for now) side mission before we get back onto type-checking variables: allowing complex expressions to exist before operators. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 042: An unexpected token means stop this expression

We&#x27;re on our way towards type-checking variables, but first we take another detour into parsing expressions: if we hit an unexpected token, we should backtrack and return what we found so far, not just stop with an error. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net Comments jezhiggins 2025-11-28 That was a journey!

Mini-rust in Rust 041: While conditions that are not operations

We are starting down a road towards type checking variables, but we go on a detour to make sure we can parse the simplest possible condition in a while loop, which it turns out we missed. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 040: While conditions should be bool

Working up towards some difficult type-checking, we do some easy type-checking: the condition part of a while condition should be a boolean, and to get there we need to improve the type we give to the result of an operation. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 039: Spans should be ranges

We&#x27;ve been tracking the location of a token in the file using a pair of numbers, but Rust has a better way: a Range . After some debate and wandering, we make the code a little better with this change. The interlude music is Blood, Collateral, & Otherwise by Hunk Golden , used under the Attribution 4.0 International License . You can find the source code at…

Mini-rust in Rust 038: Avoiding a String allocation for each token

Last time I described what I tried to do with removing the extra String stored in each Token. This time, having figured out a workaround, we go ahead and remove them. Of course, it&#x27;s more complicated than we expected. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 037: Complex expressions in mutation statements

We left a lot of gaps while we were building towards some working code. The first to tackle is allowing complex expressions on the right-hand side of mutation statements. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net

Mini-rust in Rust 036: Evaluating code blocks

Blocks of code surrounded by braces are valid statements in Rust - it&#x27;s just a small change to our existing code to be able to evaluate them. You can find the source code at codeberg.org&#x2F;andybalaam&#x2F;milk and more of my stuff at artificialworlds.net