Andy Balaam's Blog
Coding in Rust and others; making coding videos.
RustPerformance / optimizationAlgorithms / data structuresSoftware / engineering practice
- Posts
- 619 from 2 Jun 2005 to 16 Oct 2026
- Posting
- weekly (35 in the last year)
- Kind
- personal blog
- Feed
- https://artificialworlds.net/blog/rss.xml
2026 29
- Adding balls to our JezzBall clone
- Feeling sad about AI
- Web Words: what if we used 3 words to find a web site?
- Coding JezzBall in Rust+WASM
- Coding up a circular buffer with Jez
- LLMs produce plausible noise
- Parsing SGF files for fun
- A full (slow) solution to the Billion Row Challenge
- The billion row challenge: do we have a bug?
- Writing a bit-wise iterator (with Jez!) for our gunzip implementation
- Keep the faith
- Implementing gunzip from scratch in Rust
- Jez returns for programming language chat!
- Announcing Changelog Builder - a towncrier clone for building changelogs
- Using anyhow to handle errors in my Rust changelog builder
- A simpler blog comment system
- Building a Rust commandline tool: a towncrier clone
- The billion row challenge: splitting lines using SIMD in Rust
- Rust: reading very large files for the billion row challenge
- Parsing whole lines of the Billion Row Challenge
- Improving our billion-row parsers and benchmarks
- Making our own String type in Rust
- Writing a Snake game in Rust/WASM
- Talking to localhost from inside an Android emulator
- Rust: compiling to WASM to make a browser-based game using canvas
- Billion row challenge: parsing temperatures fast(ish)
- Rust: building arbitrary precision integers (badly)
- Rust: how to return a closure from a function, and what are closures anyway?
- FizzBuzz 2: FizzBuzz Harder
2025 55
- Why I don't use AI
- Converting a string to an int in Rust (for no reason)
- Why I don't use AI (expanded)
- Resizing and moving an encrypted LVM volume
- Implementing FizzBuzz in Rust (for no reason)
- Reversing a string in Rust (for no reason)
- Mini-rust in Rust 050: Parsing function definitions
- Why do I have 2 passwords? How to talk about encryption in Matrix
- Invisible Crypto: can Matrix be both secure and easy to use?
- Mini-rust in Rust 049: Lexing an empty function
- Mini-rust in Rust 048: Handling variable scope
- Mini-rust in Rust 047: Updating types as we get more information
- Jez and Andy write a Parser
- Jez learns Rust by writing a Lexer
- Mini-rust in Rust 046: Type-checking mutations
- Mini-rust in Rust 045: Combining two types when we add things
- Why I don't use AI
- Mini-rust in Rust 044: Finding the type of a symbol
- Mini-rust in Rust 043: Expressions on the left of operators
- Mini-rust in Rust 042: An unexpected token means stop this expression
- Mini-rust in Rust 041: While conditions that are not operations
- Mini-rust in Rust 040: While conditions should be bool
- Mini-rust in Rust 039: Spans should be ranges
- Mini-rust in Rust 038: Avoiding a String allocation for each token
- Mini-rust in Rust 037: Complex expressions in mutation statements
- Mini-rust in Rust 036: Evaluating code blocks
- Mini-rust in Rust 035: Tidying up the evaluator
- Mini-rust in Rust 034: Our first program, actually working
- Mini-rust in Rust 033: Evaluating operators like plusequals and timesequals
- Mini-rust in Rust 032: Supporting a Unit type and type checking mutations
- Mini-rust in Rust 031: Getting "while" through the type checker
- Mini-rust in Rust 030: Expressions after while loops
- Mini-rust in Rust 029: Parsing plus-equals
- Mini-rust in Rust 028: Lexing plus-equals
- Standing again for the Matrix Governing Board
- Testing nonexistence
- Mini-rust in Rust 027: Parsing blocks of code
- Mini-rust in Rust 026: Parsing an empty while loop
- Mini-rust in Rust 025: Parsing let mut
- Mini-rust in Rust 024: Lexing the <= sign
- Mini-rust in Rust 023: Refactor to share structure of the syntax tree
- Rust tracing basic setup
- Mini-rust in Rust 022: Stop lying about types in errors
- Mini-rust in Rust 021: Including type information in our syntax tree
- Mini-rust in Rust 020: Gaps in our type checker
- Mini-rust in Rust 019: Type checking an actual type error
- Mini-rust in Rust 018: Type checking, the happy path
- Mini-rust in Rust 017: Handling float literals
- Mini-rust in Rust 016: Tidying our parser
- Mini-rust in Rust 015: Parsing a typed assignment
- Mini-rust in Rust 014: Evaluating an assignment
- Mini-rust in Rust 013: Fixing a bug in our lexer
- Mini-rust in Rust 012: Parsing with backtracking
- Mini-rust in Rust 011: Parsing an assignment plus expression
- Mini-rust in Rust 010: Lexing an assignment
2024 70
- Mini-rust in Rust 009: Handling parsing errors
- Mini-rust in Rust 008: Refactoring our parser
- Mini-rust in Rust 007: Evaluating an operation
- Mini-rust in Rust 006: Parsing an operation
- Message order in Matrix: right now, we are deliberately inconsistent
- Mini-rust in Rust 005: Making our lexer an iterator
- Mini-rust in Rust 004: Refactoring our lexer
- Mini-rust in Rust 003: Much prettier errors
- Mini-rust in Rust 002: Errors while lexing
- Mini-rust in Rust 001: Lexing an int
- Rust 101 - 53: Exercises for module G (q4)
- Rust 101 - 52: Exercises for module G (q3)
- Rust 101 - 51: Exercises for module G (q2)
- Rust 101 - 50: Exercises for module G (q1)
- Rust 101 - 49: Foreign function interfaces (interacting with other languages)
- 19 years of blogging
- Deployment is important
- Rust 101 - 48: Exercises for module F (q3)
- Rust 101 - 47: Exercises for module F (q2)
- Heads-up: moving away from WordPress
- Rust 101 - 46: Exercises for module F (q1)
- Rust 101 - 45: Unsafe types and examples
- Rust 101 - 44: Undefined behaviour
- Rust 101 - 43: The two meanings of "unsafe" in Rust
- Rust 101 - 42: Why do we need unsafe?
- Rust 101 - 41: Exercises for module E (q2b)
- Rust 101 - 40: Exercises for module E (q2a)
- Rust 101 - 39: Exercises for module E (q1b)
- Rust 101 - 38: Exercises for module E (q1a)
- Rust 101 - 37: Async runtimes
- Rust 101 - 36: What async and await really do
- Rust 101 - 35: Futures
- Rust 101 - 34: What is async?
- Rust 101 - 33: Exercises for module D (q3)
- Elected to the Matrix Foundation Governing Board!
- Rust 101 - 32: Exercises for module D (q2)
- Rust 101 - 31: Exercises for module D (q1)
- Rust 101 - 30: Good patterns and not so good
- Rust 101 - 29: Trait objects and object safety
- Rust 101 - 28: Dynamic dispatch
- New home for my videos: video.infosec.exchange
- Why I won't link to AI resources
- Rust 101 - 27: Exercises for module C (q2)
- Rust 101 - 26: Exercises for module C (q1)
- Choosing who to vote for in the 2024 UK General Election
- Rust 101 - 25: Threads, Mutexes, channels, Send and Sync
- Rust 101 - 24: Parallelism and Rayon
- Rust 101 - 23 Exercises for module B (q3)
- Rust 101 - 22 Exercises for module B (q2)
- Rust 101 - 21 Exercises for module B (q1)
- Rust 101 - 20: Unit, integration and benchmark tests
- Standing for the Matrix Governing Board
- Rust 101 - 19: Creating a nice API
- Rust 101 - 18: Dependencies and Cargo.toml
- Rust 101 - 17: Exercises for module A3 (part 2)
- Automated backups from Signal to Nextcloud
- Rust 101 - 16: Exercises for module A3 (part 1)
- One import per line is best
- Rust 101 - 15: Lifetime bounds
- Rust 101 - 14: Some standard library traits
- Rust 101 - 13: Type Parameters and Associated Types
- Rust 101 - 12: Traits
- Rust 101 - 11: Exercises for module A2
- [Fixed in FF 123] Deleting an Indexed DB store can be incredibly slow on Firefox
- Don't store normal arrays of numbers in Indexed DB - use UInt8Array instead
- Rust 101 - 10: Strings
- Keep your Indexed DB keys and values small if you want good performance!
- Rust 101 - 9: Vecs, Boxes and slices
- Rust 101 - 8: Writing methods using impl blocks
- Rust 101 - 7: Error handling with panic and Result
2023 19
- Letter to my MP: using starvation as a weapon
- Santa Circles 0.3 is out!
- Follow this blog on the fediverse!
- Rust 101 - 6: Structs and Enums
- Rust 101 - 5: References
- Rust 101 - 4: Exercises for module A1
- Rust 101 - 3: Memory and ownership
- Rust 101 - 2: Language basics
- Rust 101 - 1: Course intro
- Combining two function types with & (ampersand) in TypeScript (intersection)
- Accessing services on the host from a Docker container or a Podman one
- Why I'm voting tactically against you - letter to my Conservative MP
- Rust WASM hello world - no need for webpack!
- Estimating software tasks and stories: avoid time-based estimates
- Maths: The Fun Parts - Graphs video
- Maths: The Fun Parts - Groups video
- Maths: The Fun Parts - Sets video
- GitHub API GraphQL snippets
- Live code reviews make life better
2022 13
- Air-Source Heat Pump - 1 year later
- Deleted my Twitter account
- IETF115 Trip Report (Can Matrix help messaging standardisation through MIMI?)
- Setting the text selection in a browser: just use setBaseAndExtent
- Tips for contenteditables
- Outreachy August 2022 update
- Transcoding video files for playback in a browser
- Matrix is a Distributed Real-time Database Video
- Building cross-platform Rust for Web, Android and iOS - a minimal example
- Deporting desperate people from the UK
- Improving my vimrc live on stream
- Comparison of Matrix events before and after "Extensible Events"
- Air-Source Heat Pump - our experience so far, 2 months in
2021 29
- Providing MapLibre-compatible style JSON from openstreetmap-tile-server
- Self-hosting maps on my laptop
- Streaming to Twitch and PeerTube simultaneously using nginx on Oracle cloud
- New game: Tron - frantic multiplayer retro action
- Preventing Virgin Media hijacking my DNS
- Letter to my MP about climate emergency
- New Job at Element (Matrix)
- What to cache when building Rust using Gitlab CI or similar
- Printing the version of a Maven project
- Minimal example of a Maven pom for a mixed Kotlin and Java project
- Importing/migrating from one peertube server to another
- Why write an entire game (including Graphics) in a single, hand-coded JavaScript file?
- Matrix is the only (chat) game in town
- Writing Snake in Terraform Video
- Suspending the computer using Kupfer
- Uploading to PeerTube from the command line
- Republishing Bartosz Milewski's Category Theory lectures
- Announcing I-DUNNO 1.0 and web-i-dunno
- Automatically filling in the UK COVID test results page with Selenium IDE
- Toggle window decorations on Linux GTK3 with Python3
- Questions about RFC 8771
- Announcing Rust I-DUNNO
- Letter to my MP on Yemen
- Making Smolpxl work on phones and tablets
- Limiting the number of open sockets in a tokio-based TCP listener
- Recommendation against the use of WhatsApp in your company
- Streaming video with Owncast on a free Oracle Cloud computer
- Pinephone update
- Is your program a function or a service?
2020 25
- Shutdown order consistency: how Rust helps
- Edge computing providers
- Schema upgrades should be reversible (also other transformations, actually)
- Make levels for Rabbit Escape using the level editor!
- Announcing Smolpxl Scores - a high score table for your game
- Dovecot not working after upgrade to Ubuntu 20.04.1 (dh key too small)
- Letter to my MP on the overseas aid budget.
- Profile a Java unit test (very quickly, with no external tools)
- Why a Free Software web games site?
- Code your first game: Snake in JavaScript (on Raspberry Pi)
- Play and create little retro games at Smolpxl
- shareon.js.org now has a Share to Mastodon button
- Coding a tiny game in JavaScript video
- short - command line tool to truncate lines to fit in the terminal
- Set the date (EXIF) of a photo on Linux
- How to send an SMS using netcat (via SMPP)
- Letter to my MP on racism in the US and UK
- Example Android project with repeatable tests running inside an emulator
- Creating a tiny Docker image of a Rust project
- Keeping track of podcast times with a simple bash script on Linux
- Custom Bash tab completion for my program
- Struggling with Rust to figure out the right types for a function signature
- React Concepts Video
- Converting HTML slides to a PDF with Firefox
- Support the Software Freedom Conservancy
2019 23
- KotlinJS: First impressions (formed by writing Snake) video
- Dependency Injection frameworks: reasons to avoid them video
- Coding workshop example worksheets
- Building an all-in-one Jar in Gradle with the Kotlin DSL
- Creating a self-signed certificate for Apache and connecting to it from Java
- ACCU Talk "How Kotlin makes your Java code better"
- ACCU Talk "How Git really works"
- Examples of Kotlin making your Java code better video
- What is a Monad? Video
- Build with a different Java version (e.g. 11) using Docker
- Rabbit Escape t-shirts
- Scheduling a task in Java within a CompletableFuture
- Rabbit Escape 0.12 out now, with water
- Convert a video to a GIF with reasonable colours
- Gradle: what is a task, and how can I make a task depend on another task?
- Python Async basics video (100 million HTTP requests)
- Keybase chat bot in 10 lines of bash
- Performance of Java 2D drawing operations (part 3: image opacity)
- Performance of Java 2D drawing operations (part 2: images)
- Performance of Java 2D drawing operations (part 1: types of operation)
- London Python Meetup January 2019 - Async Python and GeoPandas
- Run bash inside any version of Linux using Docker
- Windows missing from grub menu after Ubuntu install
2018 33
- New home page design
- Code Like a Girl T-shirts
- Poor performance in Chrome (especially on mobile) - caused by SVG background images
- Interesting Characters (UTF-16, utf-8, Unicode, encodings) video
- Elm makes me happy (updated for Elm 0.19) video
- Godot: make new objects at runtime (instancing) video
- You must rewind your incoming buffer when you fail to encode a character in a CharsetEncoder or you'll get an IllegalArgumentException
- Godot: Dragging and dropping physics objects video
- Godot: 2D shapes bouncing off each other video
- Elm JSON decoder examples
- Graft Animation Language on Raspberry Pi
- Worksheet: "Tell a story by making animations with code"
- My experience upgrading to Elm 0.19
- Bulk adding items to Wunderlist using wunderline on Ubuntu MATE
- Writing a new Flarum extension on Ubuntu
- Ubuntu "compose" key for easy unicode character input
- Redirecting all requests to https and www using .htaccess in Apache
- Example of a systemd service file
- Installing Flarum on Ubuntu 18.04
- Rabbit Escape 0.11 out now!
- Migrating videos from YouTube to PeerTube inside a Docker container
- How to write a programming language articles
- Allow drag-to-side, but not drag-to-top in Ubuntu MATE (Marco)
- Connecting to Slack from an IRC client using slirc
- Using Matrix to connect to Slack from an IRC client on Ubuntu
- Clever Things People Do In Groovy So You Have To Know About Them video
- Examples of SQL join types (LEFT JOIN, INNER JOIN etc.)
- Fixing Slack emojis in HexChat
- Ideas on how lexing will work in Pepper3
- Deleting commits from the git history
- Questions and answers about Pepper3
- Examples of Pepper3 code
- Recording gameplay videos on RetroPie
2017 28
- TECH(K)NOW Day workshop on "Writing a programming language"
- FileZilla with proxy not working with strange characters in the password
- HTML5 CSS Toolbar + zoomable workspace that is mobile-friendly and adaptive
- maven-assembly-plugin descriptor for a simple tarball with dependencies
- Blog aggregator/planet in WordPress using FeedWordPress
- Adding a day in Python datetimes - use timedelta, not the datetime constructor
- Broken Levels Challenge - Egham Raspberry Pi Jam July 2017
- Women Who Code workshop on "Write your own programming language"
- Running a virtualenv with a custom-built Python
- Adding a concurrency limit to Python's asyncio.as_completed
- "git what" is "git status" on steroids
- Making 100 million requests with Python aiohttp
- Python - printing UTC dates in ISO8601 format with time zone
- Python 3 - large numbers of tasks with limited concurrency
- Basic ideas of Python 3 asyncio concurrency
- C++ iterator wrapping a stream not 1-1
- How to write a programming language ACCU talk
- C++ iterator wrapper/adaptor example
- C++ iterator example (and an iterable range)
- Make Android Gradle display unit test failure messages
- Planet Code updates
- A story about magic and how we treat each other
- Annual cost of clean water for every human
- Iterating over the lines of a file in Java
- Raspberry Pi Jam "Chaos Car!"
- Automated UI tests on Android
- Submitting a package to F-Droid
- Resources for year 6 teachers on coding and programming
2016 21
- Setting up a sane Maven project
- Writing a unit test in Elm
- How to write a programming language - Part 3, The Evaluator
- Basic Haskell project setup (unit tests, code, formatting)
- How to write a programming language - Part 2, The Parser
- Mousedown events delayed or sluggish on mobile
- How to write a programming language - Part 1, The Lexer
- Simple example of Netty 4 usage
- Elm resizeable SVG canvas filling the screen
- Ambiguous names in Java due to non-normalised unicode - but all OK in Python
- Gracefully shutting down Firefox, to avoid the crash/session dialog
- Snake in Python 3 + Qt 5
- Basic Concepts of Christianity video
- Elm Basics Video
- How to analyse a .phd heap dump from an IBM JVM
- Elm makes me happy (old: Elm 0.17)
- What's new in Java 8
- Which Raspberry Pi photo was funniest?
- Raspberry Pi Funniest Photo Game
- Snake in Elm
- Out-of-school education settings
2015 43
- New open source project on work time - git-history-data
- Java HTTPS to a server with a self-signed certificate
- Vim as editor for Claws Mail
- Using GitHub and GitLab
- Avoiding postfix error "status=deferred (unable to look up host"
- Finding the download count of GitHub releases
- Android: using a TextView to show rich text in an AlertDialog
- Assassination of individuals by the state
- Difficult merges in Git - don't panic!
- ZX Spectrum BASIC Web Server
- Letter to my MP on UK government assassination of British Citizens in Syria
- Rabbit Escape out now on Android!
- Changing the Docker daemon options in systemd on Ubuntu 15.04
- Docker fails to start on Ubuntu 15.04
- Preventing Audacity from crashing when using PulseAudio
- Movie podcast "The Good Robot Andys"
- Code for detecting when you leave an Android app
- Mocks are Bad, Layers are Bad
- Prediction result: corporate Linux
- Detecting whether an Android app is stopping (or starting)
- Order of Android Activity lifecycle events
- Snake in Dart
- Preventing Kupfer switching to existing windows
- Using Kupfer on MATE
- Tweetable Art Code
- Rabbit Escape 0.3.1 - now with zoom!
- Treat warnings as errors in a (Gnu) Makefile
- Switching Xfce to use metacity
- Java game programming: image rendering hints make no difference to rendering time
- Snake in ZX Spectrum BASIC
- fetchmail complaining about GoDaddy SSL certificate
- Encapsulation as passing on responsibility
- Snake in Ruby
- Batch-converting audio files to be louder (on Linux)
- Why Rabbit Escape is Open Source / Free Software
- What is a good company?
- How to make your own levels for Rabbit Escape
- Rabbit Escape v0.1 out now for Linux, Windows and Mac video
- Rabbit Escape (a bit like Lemmings) v0.1 released for Linux, Windows and Mac
- Snake in Groovy
- Programmatic equivalents of web.xml sections for Tomcat
- JAX-RS (using Apache CXF) in embedded Tomcat example
- Vim persistent buffer list combined with saved sessions
2014 41
- Snowflake Christmas card web page on the Raspberry Pi
- Snowflake Christmas card in Scratch on the Raspberry Pi
- Encoding URLs in Java
- Books that changed my life
- Why I use Linux
- LibreOffice spell check not working in Lubuntu
- Is it ok to represent dates as Unix time (seconds since the epoch) in JSON?
- Using hexdump to represent a binary file in Java source code
- Disabling screensaver on LXDE
- Android development - saving state
- Android development - Rabbit Escape really working on Android
- Showing urgent (flashing) windows on all desktop in LXDE's taskbar (window list) in Lubuntu
- Launch an urgent window using Python and Xlib with the UrgencyHint flag
- Android programming - a non-Android, Android Game
- Android programming - drawing bitmaps in a game loop
- Don't use email auto-forwarding (emails will go missing)
- Fetchmail "mda" option makes emails bypass the spamassassin filter in postfix
- Android programming - a menu using Activities and Intents
- Raspberry Pi Minecraft Python summer project screenshots
- Android programming - setting up Android Studio
- What is a string?
- Absolute Truth in programming languages
- Options for code reviews with Git
- Desktop sharing not working in Lubuntu 14.04
- Best GCC warning flags for compiling C++
- What git server should I use?
- Renewing self-signed certificate for ejabberd
- Letter to my MP on DRIP
- What is node.js?
- A mini mocking framework
- Simple template programming
- Five Quines video
- OpenID security in a REST API
- avconv performance slow in Ubuntu 14.04 trusty
- Does test-driven development harm clarity?
- Token-based security in a REST API
- Avoid mocks by refactoring to functional
- Using the final keyword in interface method parameters does nothing
- Using xscreensaver to lock the screen in Lubuntu
- Security in a REST API
- Searching in a REST API
2013 26
- Paging in a REST API
- A Basic REST API
- Avoid backslashes anywhere in Java code (Java error "illegal unicode escape")
- What is REST?
- Bash arrays
- Using if:set, unless:set etc. with macrodefs in Ant
- Using if:set, unless:set etc. to execute a task conditionally in Ant
- Vim for Fun
- Working with others in git
- Merging in git
- Behaviour of Java String.split() when some answers are the empty string
- Checking the case of a filename on Windows
- Branches in git
- Passing several values through a pipe in bash
- Goodness in programming languages, part 4 - Ownership & Memory
- How to use git (the basics)
- Using gnome-mplayer to play DVB radio without asking whether you want to resume
- C++14 "Terse" Templates - an argument against the proposed syntax
- setUp and tearDown considered harmful
- Why use git for source control?
- Set the volume in OpenBox/LXDE (or on the command line) with PulseAudio and Ubuntu
- Everybody loves build.xml (test-driven Ant)
- Everybody hates build.xml (code reuse in Ant)
- Dry run mode for Ant (ant -n, ant --dry-run)
- My First Raspberry Pi Game " Part 12 " Scoring, done!
- My First Raspberry Pi Game " Part 11 " Being less rude
2012 42
- My First Raspberry Pi Game " Part 10 " Red square
- My First Raspberry Pi Game " Part 09 " Lots more words
- My First Raspberry Pi Game " Part 08 " Success and failure
- My First Raspberry Pi Game " Part 07 " A green circle
- Launching an OSGi app on the command line
- My First Raspberry Pi Game " Part 06 " A better class of waiting
- My First Raspberry Pi Game " Part 05 " Say something
- My First Raspberry Pi Game " Part 04 " A small black screen
- Length of Open Source licenses
- My First Raspberry Pi Game " Part 03 " It's like a magic spell
- My First Raspberry Pi Game " Part 02 " Saying hello
- My First Raspberry Pi Game - Part 01 - Before we start
- Running Dojo DOH tests in a browser without a web server
- Bash associative array examples
- Running Dojo 1.7+ DOH unit tests on the command line with Rhino
- Lambda functions timeline
- Goodness in programming languages, part 3 " not doing the same thing more than once
- Tail Call Optimisation in C++ - lightning talk video
- Cool Raspberry Pi Projects
- Scheme 7: Macros video
- Scheme 6: Lambda video
- Tail Call Optimisation in C++ published in Overload journal
- Scheme 5: Quotation video
- Scheme 4: Recursion - how to write functions in Scheme video
- Scheme 3: Closures video
- Scheme 2: Basics - pairs and lists video
- Scheme 1: Feel the cool video
- Generalising tail call optimised C++
- JavaScript WTFs Videos
- Closures in Scheme
- Performance of tail call optimised C++
- Tail call optimisation in C++
- Lighting talk - Tail call optimisation in C++
- Scheme: pairs, lists and recursion
- What timezone Python thinks I'm in
- Freeview dvb-t scan gives "tuning failed!!!" after 18th April switchover
- Scheme: feel the cool
- JavaScript WTFs
- Goodness in programming languages, part 2 " getting your code running
- Building jEdit from source
- Goodness in programming languages, part 1 - syntax and layout
- Ethernet not working on Ubuntu with Realtek RTL8111/8168B
2011 8
- FreeGuide usage stats
- Entertain your baby using your Android phone
- rdesktop swallows keyboard events
- Reclaiming desktop space with Ubuntu's window-picker-applet
- My Address Book 1.9.0 - rewritten from scratch
- Switching workspace in GNOME via the command line
- Anatomy of an interpreter: the Evaluator
- How to ask technical questions in person
2010 5
2009 16
- FreeGuide 0.10.11
- Don't design for performance until it's too late
- Technorati appear to have broken openid delegation
- NNDB 0.1
- NNDB's Not a Database
- Diffident 0.3
- CBeebies and other channels not working with mplayer
- Firefox keyword search for finding C++ keywords
- Flaws in the software patents system
- IGCC - a real-eval-print loop for C/C++
- Diffident - command line side-by-side diff editor
- Random background in GNOME
- Analog literals
- Separate regular expressions, or one more complex one?
- New Baby
- Talk in code
2008 12
- Fixing the vertical panel window list on Ubuntu Hardy
- An actual difficult bug fixed
- FreeGuide 0.10.9
- Wii repaired free!
- Another one
- FreeGuide 0.10.8
- Debugging memory use and fragmentation on Windows using Address Space Monitor
- C++ is an expert language
- Templated test code?
- Public bzr branch of FreeGuide
- Public git repo for GSSMP
- Finally released last.fm support for GSSMP
2007 27
- lighttpd on Ubuntu - alias.url doesn't work when included in a module config file
- FreeGuide updated to latest XMLTV, and bug fixes
- duckmaze 0.2
- Caution: numbers that feel prime may be divisible by 3
- Announcing Record TV
- FreeGuide 0.10.5
- FreeGuide SVN now useable
- Heartfelt apologies for the feed URL change
- FreeGuide - putting recording on hold
- New Baby arrived safely
- (Badly wrong) usage statistics for FreeGuide
- Procmail Maildir messages disappearing
- last.fm in GSSMP
- lastfmsubmitd on Ubuntu Dapper
- Obviously, there was a bug
- Watching TV: a simpler way
- GSSMP 1.0
- Choose channel dialog
- Digital TV on Dapper with my Hauppauge WinTV Nova-T card
- Restoring a backup with Duplicity
- Remote encrypted backup with duplicity
- GSSMP goes beta
- Recording in FreeGuide
- My daily backup
- Creating .deb and RPM packages
- Moved to WordPress
- Two new babies
2006 18
- New games!
- Linux Journal - Forgiveness
- Another FreeGuide release candidate
- FreeGuide 0.10.4 release candidate
- A Quick and desperate introduction to data recovery
- FreeGuide fan mail
- Over-engineering gone mad
- Keyboard layout change in Ubuntu
- FreeGuide source layout (and SVN migration)
- Letter to Linux Journal
- Linux Journal slides
- Donation
- FreeGuide update
- Faster Poker Analysis
- Poker Analysis
- Podcasts I listen to
- Setting up my ideal email system 4
- I spawn
2005 36
- Setting up my ideal email system 3
- FreeGuide 0.10pre2
- Setting up my ideal email system 2
- Setting up my ideal email system
- Just a little bit longer...
- BashPodder
- Python objects in C++
- CD writing on Fedora Core 3
- Prince of Persia - The Sands of Time
- Personal stuff is boring
- Sourceforge
- London
- London terrorist attacks
- The dangers of learning to code
- Train gaming
- Constantly changing passwords
- Gaming on the move
- ATV Palm export
- Nearing a new release
- DIYPlanet
- Re-implementing
- Honestly my last post about my viva
- Corrections
- Viva today
- Mnemonic
- FreeGuide's TODO list
- FreeGuide packaging and plugins
- DIYBlog
- RSS working?
- Prediction: corporate Linux
- Guilty Expression
- Rss 2
- A real job
- What is going on with FreeGuide?
- Beginning blog