RSSAmplifier

Blog

mgmarlow.com - List of blog posts

Graham Marlow on the internet.

mgmarlow.comRSS feed ↗74 posts

Latest posts

868-BACK is my new favorite roguelike

Into the Breach is fantastic because it captures a particular kind of magic moment. Procedural generation serves up an absolute doozy of enemies and objectives, a configuration that feels insurmountable. You try your usual tactics but nothing sticks. Minutes float by as you reconfigure your mechs and undo yourself through an entire possibility space. Just as you're about to lose hope a…

Creative inconstanty

Xbox finds itself in the midst of a C-suite rotation and the classic destruction of thousands of jobs that follows. As the gaming industry grapples with an overwhelming churn of creative talent, the internet waxes poetic about the creative ability of some of the surviving studios. The discourse around Obsidian has really rubbed me the wrong way. "The number of times I've seen people, with no…

Revisiting My Reading List

The best kind of weekend project takes just a few scattered hours while solving a supremely pedantic annoyance. That's the story of my hand-rolled book-tracking replacement. The idea stemmed from a discussion with friends, where a conversation about books transitioned into how we keep track of our respective lists. Unlike Letterboxd, which solves movie-tracking with a sublime grace, every…

PGP and Real-World Cryptography

My previous post details setting up Sequoia PGP for email encryption, where I gloss over technical details in favor of waxing poetic about the virtues of privacy. That's all well and good, but I don't want to leave such details completely behind because they form an interesting window into the world of asymmetric cryptography. This whole PGP excursion has ignited within me a desire to…

Email Encryption with Sequoia PGP and Thunderbird

The Discord Face ID debacle has reminded me that centralized platforms routinely abuse user privacy. I can empathize with the desire to protect underage users, but requiring facial identification is overreach. It's especially insulting when Discord leaked some 70,000 government IDs in October 2025 under similar pretenses. While my friends and I scour the web for an alternative place to call…

Coding with Agents; Managers and Builders

Like many software engineers I've been experimenting with coding agents as part of my day job. 1 My approach is still in its infancy: a handful of tabs and sessions organized by tmux, terminal split in half while coaching Claude through planning and implementation, mostly focusing on just one task at a time. I haven't seen the productivity boost lauded by tech executives, but I remain…

Prototyping a Chess Puzzle Game

Monster Chess is my attempt at a chess puzzle game that doesn't require any knowledge of chess except the movement of the pieces. Rules of Monster Chess: You can only move white pieces. Capturing a piece turns your current piece into the kind that you captured. Pawns do not promote on the back rank. You can refresh the page to reset the level. There are 12 puzzles in all. Give them a try !…

Guide to Cryptic Crosswords

The cryptic is a special kind of crossword that is unfortunately lacking popularity in the US. Unlike it's American counterpart (e.g. the NYT daily), every clue in a cryptic utilizes some kind of misleading wordplay. The result is a crunchy (and hilarious) word puzzle that is a delight to solve. To the uninitiated, the cryptic crossword is downright indecipherable. To the initiated, well,…

Why React Matters

A recent popular article compares React to Backbone , arguing that React is not much of an improvement. I think this article profoundly misses the point. And I don't even like React! Before discussing what the article gets wrong, I want to quickly mention what it gets right. These bullet points captured from the article are a great list of React-isms that are worthy of criticism: key as a…

A Thorough Look into RBS for Rails

Back in 2020, Ruby 3.0 introduced a system for writing type definitions for Ruby programs called RBS. Five years later, I rarely hear about it being used in production Rails apps. The situation is somewhat similar to Ractors, another feature released with Ruby 3.0. The idea of Ractors brought a ton of buzz to the Ruby community because it directly answered one of the major pain points of the…

Deno's stdlib is Available Outside Deno

Out of the craziness that has been the last couple weeks of NPM supply-chain drama we're reminded that Deno at least had a few things right when it pushed for a secure-by-default stance towards third-party code. In the same general space we've seen Pnpm disable postinstall scripts by default and more recently release some minor mitigating configuration settings . It is certainly an…

August Was a Great Month for Puzzles

I can't stop thinking about two puzzle games that came out last month. They're both the kind of game that makes me jealous for not having designed it myself, then jealous again for knowing that even with the idea in my hands I couldn't execute it as well. Those two games are Strange Jigsaws and Öoo . Strange Jigsaws is a meta-puzzle exploration built on the humble jigsaw puzzle. If…

New Emacs Package: Helix Mode

Short version: I'm building a new Emacs package: Helix Mode . Helix Mode implements the Helix modal keybindings in Emacs. It's been my daily driver for about a month, and while it still has some bugs, I'm reasonably confident it's in a usable state. Install Helix Mode in Emacs 30.1: ( use-package helix :vc (:url "https://github.com/mgmarlow/helix-mode" )…

Action Cable + React

Using Action Cable in React is surprisingly difficult. Every third-party package that I've come across that offers a custom hook makes some fundamental assumptions that only hold for simple applications. The vast majority of tutorials gloss over anything beyond the "log when event is received" boilerplate. The principle of integrating Action Cable is easy, since it follows a well-known…

Kafka on the Shore is My Favorite Murakami Novel

The following is an email I sent a friend regarding Kafka on the Shore. I've had a week or two now to digest Kafka on the Shore and put some thoughts together. It's definitely my favorite Murakami novel thus far. By a long shot. The symbolism feels attainable, yet abstract enough that there's still room for reader interpretation. The plot is interesting enough to give weight to the…

How I Organize Email with HEY

Six months after swapping back over to HEY for email feels like the appropriate time to check in on how it’s going. Here are the ways I use HEY to organize my email; what works and what doesn't. My workflow I read every email that finds its way into my inbox. I hate unread emails, and I especially hate the # unread counter that most other email platforms surface within their tab titles. It…

Visualizing Bracket City Puzzles

Lately I've been addicted to a new daily word puzzle game called Bracket City . It's unique among competitors because the game isn't about rearranging letters baked in hidden information, but rather solving hand-written, crossword-style clues. I recommend giving the daily puzzle a shot before reading the rest of this article since it will help with visualizing the puzzle format. But…

Onboarding a new Mac

My process for onboarding a new Mac: Remove all of the apps from the default dock. Move the dock to the righthand side and set to minimize automatically. Rebind Caps Lock as Control via Settings->Keyboard->Modifier Keys. Install the usual software: Firefox Developer Edition Alacritty (terminal emulator) Rectangle (windowing solution) Hack (monospace font of choice) 1Password Homebrew Install git…

Ruby and RSS feeds

I've been digging into Ruby's stdlib RSS parser for a side project and am very impressed by the overall experience. Here's how easy it is to get started: require "open-uri" require "rss" feed = URI . open ( "https://jvns.ca/atom.xml" ) do | raw | RSS :: Parser . parse ( raw ) end That said, doing something interesting with the resulting feed is not quite so simple.…

Reminiscing on Flow

(The type-checker , not the state of deep work) React's recent sunsetting of Create React App has me feeling nostalgic. My first experience with a production web application was a React ecommerce site built with Create React App. I came into the team with zero React experience, hot off of some Angular 2 work and eager to dive into a less-opinionated framework. The year was 2018 and the team…

Zod refinements are complicated

Today I found myself at the bottom of a rabbit hole, exploring how Zod's refine method interacts with form validations. As with most things in programming, reality is never as clear-cut as the types make it out to be. Today's issue concerns zod/issues/479 , where refine validations aren't executed until all fields in the associated object are present. Here's a…

Modularizing Start Emacs

Some folks don't want their entire Emacs configuration to live in a single, thousand-line file. Instead, they break their config into separate modules that each describe a small slice of functionality. Here's how you can achieve this with Start Emacs . Step one: load your custom lisp directory Emacs searches for Emacs Lisp code in the Emacs load path . By default, Emacs only looks in two…

Async IO in Emacs

Stumbled on the emacs-aio library today and it's introduction post . What a great exploration into how async/await works under the hood! I'm not sure I totally grok the details, but I'm excited to dive more into Emacs generators and different concurrent programming techniques. The article brings to mind Wiegley's async library, which is probably the more canonical library…

Pulling Puzzles from Lichess

Lichess is an awesome website, made even more awesome by the fact that it is free and open source. Perhaps lesser known is that the entire Lichess puzzle database is available for free download under the Creative Commons CC0 license. Every puzzle that you normally find under lichess.org/training is available for your perusal. This is a quick guide for pulling that CSV and seeding a SQLite…

Logseq Has Perfected Note Organization

A little while ago Apple Notes left me with quite the scare. I booted up the app to jot down an idea and found my entire collection of notes erased. I re-synced iCloud, nothing. Just the blank welcome screen. Luckily my notes were still backed up to iCloud, even though they weren't displaying in the app (I checked via the web interface). After 40 minutes of debugging and toggling a series of…

Paper Puzzle Remixes

The holidays are always a great time for puzzles. My parents still receive print newspapers, offering an ideal opportunity to catch up on crosswords. This year I also picked up NYT's Puzzle Mania , a treasure-trove of paper puzzle goodness. Just a few days ago my partner and I finished the whopping 50x50 crossword puzzle. That's over 1000 clues! What struck me as especially interesting…

Best of 2024

I'm always surprised when distilling a year into a single post just how many things take place over those 365 days. When I'm in the thick of it I'm rarely thinking about the details. Events and projects come and go, rarely do I take a step back and properly register their impact or my feelings. So forgive me a moment of catharsis. Game development I made a game! It's a little…

Automating Quick Notes with iOS Shortcuts

I've blogged before about why I really dislike apps like Notion for taking quick notes since they're so slow to open. The very act of opening the app to take said note often takes 10 or more seconds, typically with a whole bunch of JavaScript-inflicted loading states and blank screens. By the time I get to the note, I've already lost my train of thought. As it turns out, this…

Solving Puzzles by Making Puzzles

This year I've substantially buffed up my crosswording skills. Mon-Wed on the NYT pose no threat, and I can even occasionally solve the Thu/Fri without checking an answer. Saturday remains befuddling. One reason for my skill improvement is repetition. The more puzzles I solve, the more I recognize clue patterns and common words. Drill those puzzles frequently enough and skill inevitably…

The Most Common React Mistake

The React homepage promises that "learning React is learning programming" and I think the framework somewhat delivers on it. At the very least you don't need to learn a new templating language thanks to JSX. That said, don't be completely fooled by this promise. Like every other JavaScript framework, React is full of subtle complexities and esoteric nuances that have nothing to do with…

Type predicates to avoid casting

Type predicates have been around but today I found a particularly nice application. The situation is this: I have an interface that has an optional field, where the presence of that field means I need to create a new object on the server, and the lack of the field means the object has already been created and I'm just holding on to it for later. Here's what it looked like: interface…

Data migrations with data-migrate

What I traditionally would've used Rake tasks for has been replaced with data-migrate , a little gem that handles data migrations in the same way as Rails schema migrations. It's the perfect way to automate data changes in production, offering a single pattern for handling data backfills, seed scripts, and the like. The pros are numerous: Data migrations are easily generated via CLI and…

Cool Rails concerns

There's something super elegant about Writebook's use of concerns. I especially like Book:Sluggable : module Book :: Sluggable extend ActiveSupport :: Concern included do before_save : generate_slug , if : -> { slug . blank? } end def generate_slug self . slug = title . parameterize end end Here's a few reasons: Nesting concerns in a model folder is neat when that concern is an…

Why I Still Use Apple Notes

My list of reasons for using Apple Notes isn't very long. In many ways I think Apple Notes is an inferior app, especially when comparing it to alternatives like Notion, Obsidian, and the like. There is one thing that keeps me using it, however. Simplicity. Organization is a death sentence for spontaneity. Tools like Notion have me questioning my note placement before I've written a…

Exploring the Writebook Source Code

Earlier this year 37signals released Writebook , a self-hosted book publishing platform. It's offering number two from their ONCE series, pitched as the antithesis of SaaS. Buy it once and own it for life, but run it on your own infrastructure. Unlike the other ONCE offering, Writebook is totally free. When you "purchase" it through the ONCE checkout, they hook you up with the source code and…

HEY to Fastmail and Back Again

I've read a few stories about folks moving their email from HEY to Fastmail, but have not seen any in the reverse direction. After two years of Fastmail, I'm moving back to HEY. Here are my thoughts. For those unacquainted with HEY, the main pitch is (a) screen unknown senders (b) into one of three locations: "Imbox", "The Feed", and "Paper Trail". Senders that are "screened out" are…

Crafting Interpreters, Ruby Style

I finally have started working through Crafting Interpreters , a wonderful book about compilers by Robert Nystrom. The book steps through two interpreter implementations, one in Java and one in C, that ramp in complexity. Now I don't know about you, but I hate Java. I can hardly stand to read it, let alone write it. That's why I decided to write my first Lox interpreter in Ruby,…

New stuff in Emacs 30

Emacs 30.1 is near on the horizon with the most recent pretest (30.0.93) made available in late December . This post highlights some new features in the upcoming release that I find especially compelling. If you want to know everything that's upcoming, check out the full release notes . Native compilation enabled by default This is huge! Native compilation was introduced in Emacs 28 behind a…

Recently

Recently I've been deep down a crossword puzzle rabbit hole. I started a new side project that has taken most of my writing energy: them's crossing words , a blog where I post daily crossword puzzle reviews and articles about the craft of puzzle construction. Thus far there's about fifty crossword puzzles featured and discussed, a sizable number of grids with over 10k words…

Markdown Rendering with Awk

I can't believe I'm writing another post about Awk but I'm just having too much fun throwing together tiny Awk scripts. This time around that tiny Awk script is a markdown renderer, converting markdown to good ol' HTML. Markdown is interesting because 80% of the language is rather easy to implement by walking through a file and applying a regular expression to each line. Most…

DM Tools with Awk

I picked up Awk on a whim and am blown away by how generally useful it is. What I thought was a quick and dirty tool for parsing tabulated files turns out to be a fully-featured scripting language. Before I started reading the second edition of The Awk Programming Language , my only exposure to Awk was from better-minded folk on Stack Overflow. After copy-pasting a short script here or there, I…

A Few Months with Kagi

I've subscribed to Kagi for a few months now and wanted to collect some of my feelings towards it, particularly addressing whether I think it's worth paying $10/mo for a search engine. To summarize: yes, I do think Kagi is worth the price. Kagi performs as good or better than the competition for the majority of things I search (programming stuff and a healthy dose of Emacs) and…

My Year in Reading

I read 24 books in 2023, a total of just over 8,000 pages. It was an uncommonly productive year for me, not driven by any particular goal but rather a general interest in a few choice authors and compelling works. Here are some of the highlights. Murakami I read four different books by Haruki Murakami this year, starting with What I Talk About When I Talk About Running and following up with…

How to Install React

Tsoding's recent stream about React is a hilarious reminder of the complications of web development tooling and the lack of support for beginners who want to take a bottom-up approach to learning. What I found most surprising about his foray into React is actually the React documentation itself. It fails to provide any detail into setting up a React build environment yourself, instead…

Hypermedia and Hyperbole

My partner and I are slowly working our way through the Myst series and have finally started Myst 3: Exile. We were both surprised by how much of a departure this entry is to the previous Myst games. The biggest change isn't so much the game itself as it is the implementation of freelook: the ability to look around a scene like it's a three-dimensional room. If this doesn't sound…

Recently

I'm taking a page from Tom MacWright's blog and am trying out a "Recently" series, where I summarize a few things on my mind since my last post. Recently I've been tinkering with Crafted Emacs , a modularized Emacs starter kit. The project strongly invokes one of my favorite things about the Emacs community: taking bits of insight from other configurations and sprinkling them into…

Deno + Tree Sitter + Emacs

I've been spending a bunch of time fiddling with Deno lately, mostly in the form of small scripts and Fresh projects . One thing that hasn't impressed me doesn't have anything to do with Deno itself but rather the tooling around it: setting up Deno with Emacs is a little cumbersome. The problem roots to Deno and TypeScript sharing a file extension ( .ts ). While this doesn't…

Building a Compiler for My Static Site Generator

My side project has exploded in scope. My original goal was to build a static site generator to learn how they work, not to support lots of features. Yet here I am building a compiler for my own template language. Before the compiler, I had a very simple model for handling templates focused around variable replacement. That is, given some mustache expression , replace the requested variable with…

Small Weekend Projects

I love small weekend projects. A project completed in two days is either smartly scoped or hacked together; the core of a great idea that's been sitting in the back of your mind or a feat of engineering spontaneity that is given just enough space to flourish into reality. Either way it's a great way to learn new things. I was compelled this weekend to build my own static site generator ,…

Building a Flymake Backend for Clippy

Last weekend I had a great time building my own Flymake backend for Clippy (the Rust linter): flymake-clippy . If you haven't heard of Flymake, it's old-school Emacs tech for showing squiggly-lines in your editor. You can build your own Flymake extensions by creating a function, referred to as a backend, that collects diagnostics and reports them to Flymake. Register that backend in your…