In the early days, computers were machines that could take up an entire wall, and users interacted with them via teletypes. This electronic typewriter could be in the same room as the computer, in a building next door, or in an operator’s residence where they would connect it to their home telephone and dial in. Line editors like Ed the standard Unix text editor were a good fit for the technical limitations of the day: the “command / response” model of editing works well when you can immediately see your commands printed onto the teletype paper even if the response requires a long round-trip to the nearby university.
read more →AI assisted agentic coding has reached escape velocity, but non-programming use cases haven’t seen the same degree of adoption. I believe that the main reason for this is the lack of version control.
Imagine using claude-code outside of a git repository. Even for small things like refactors, using AI would be very stressful and error prone:
It would be near-impossible to track the changes that the LLM made. Auditing the LLM generated code is useful in the moment to ensure that changes are reasonable before moving on to another task, and in the future when you want to understand why some code was written The LLM could put the codebase in a bad state and you’d have no way of reverting This is true even if the LLM is incredibly smart and didn’t make any “mistakes” - the human prompter forgetting to tell it about a design constraint could be bad enough There’s no split between the “development branch” and “prod” You can’t parallelize development by having multiple LLMs work on different branches Even when I pay Claude to work on a small script, I always create a new git repo just to make my life easier.
read more →I read a lot of programming blogs on my phone, and code blocks that don’t fit width-wise on the screen are a major source of irritation. Unlike prose, code blocks won’t be dynamically formatted Ok, but maybe it could? Imagine compiling rustfmt to wasm, and embedding it in the page so that every screen size would have the code formatted perfectly? based on the available space on the page, so you’re stuck with code that is usually 80 characters wide, causing horizontal overflow that forces me to scroll left and right to follow the code.
read more →Um Actually has a broken scoring system, but we can fix it!
read more →Things I like:
vim keybindings in the file browser AI integration is pretty great, especially the streaming bash Things I dislike:
: brings up the whole command palette. I habitually save files (:w) in order to run my code formatter. I really don’t like how disruptive the command palette is. AI integration Some bash tasks timed out, but didn’t successfully kill the cargo test processes
read more →“Folks on IRC say that cool people use vim. I want to be cool! I’ll use vim”. Not the best logic, but I was 14, and it was only the second worst decision I made that day (Arch user btw). Vim (and later Neovim) have been constant companions throughout my journey as a programmer, and I’m very glad that I paid down the cost of learning a complex editor at a time where wrestling with my development environment was mainly just preventing me from making bad flash games.
read more →In 2014 while I was an intern on the Dart Language team, Google hired Erik Meijer as a consultant to
work on Dart’s async / await compiler. Erik is an world class expert in this domain, but was
unfamiliar Dart, so they had a senior member of the team sit next to him all day to smooth over the
bumps that people usually hit when learning a new language and codebase. I think the senior dev also
did much of the typing, but I’m more fuzzy on that.
Recently I’ve been using LLMs to write code for some algorithms research. I chose Rust even though I
haven’t used it in ~8 years, and with the AI assistance, the workflow is close to what I imagine
Erik had. I’m still reviewing and making modifications to the LLM-generated code, but almost all of
my labor is at a layer above the programming language.
It’s fun, and certainly a productivity boost, but it’s not how I want to do every project. I still
like programming by hand because I enjoy the process of learning and refining my craft, and in the
past few weeks, I haven’t learned much about Rust. The code Claude has written seems fine, but I
wouldn’t vouch for its cleanliness or correctness, which is fine in a research setting, but wouldn’t
cut it for code that I would feel comfortable running in production.
SVG filters and backdrop-filter cross-browser compatibility
I tried adding blurred, grainy backgrounds to blog posts using CSS filters and SVG. The goal was simple: take a background image, blur it heavily, add film grain texture, and make it scroll with the page content. What I found was a mess of browser compatibility issues.
Initial Approach: Direct Blur on Background Image The obvious first attempt was applying filter: blur(100px) directly to an element with a background image:
read more →In the hopes that I’ll start regularly blogging soon, I decided to use a real static site generator
instead of the cobbled-together mess of Makefiles and pandoc that I used before.
Less than a day into using it, I’m already regretting the decision to go with hugo. I built a hugo
“shortcode” that pulls comment-delimited content from external files into the markdown files in
order to keep source code in the blog posts up to date. It works pretty well!
The main downside is that I can’t figure out how to dedent the code that is being imported this way,
so if you pull in an OCaml function that is defined inside of a few nested modules, all the code
keeps the original indentation, causing the alignment to be very ugly. If anyone knows how to fix
this, please let me know!
This post demonstrates how to inline code snippets from external source files using Hugo shortcodes.
Overview Instead of copying code into markdown files, we can maintain source code separately and pull specific regions into our posts. This keeps code DRY and ensures examples stay in sync with actual source files.
Example: A Simple Parser Let’s look at a toy parser implementation. First, we define our token types:
#[derive(Debug, Clone, PartialEq)] enum Token { Number(f64), Identifier(String), Plus, Minus, Star, Slash, LeftParen, RightParen, } The tokenizer needs to handle numbers specially, since they can span multiple characters:
read more →This is a test of sidenotes. Here’s some text with a sidenote. This is the first sidenote. It should appear in the margin on large screens, or toggle inline on smaller screens. The main text continues after the sidenote reference.
Here’s another paragraph with more content. Sometimes you want to add additional context Like this second sidenote, which provides supplementary information without interrupting the flow of the main text. without breaking up your main argument.
read more →warning: the posts below this point are pretty old!
Today Bincode hits 1.0.0! Before we truly get started, a brief history:
Sep 15 2014 First prototype - then named writer_encoder - was written while I was on a plane with no wifi. Oct 27 2014 Rename to bincode Apr 05 2015 Initial port to serde written by erickt Prior to this, we were using rustc-serialize Aug 08 2015 Servo starts using bincode in ipc-channel Jan 12 2016 Tarpc starts using bincode Apr 21 2017 Serde hits 1.
read more →A new way to shape
Implicit-GPU is a new 2d CAD program based on the principals of Constructive
Solid Geometry (commonly refered to as CSG). What makes Implicit-GPU
different is the implementation detail that shapes are described mathematically,
allowing them to be rendered at low resolution for quick feedback and infinite
resolution for publishing.
read more →In object-oriented languages, it is common to have collections containing objects that implement a certain interface.
interface Animal { ... } class Cat: Animal { ... } class Dog: Animal { ... } List<Animal> listOfAnimals = ...; And while this is certainly possible in rust by using trait-objects,
trait Animal { ... } let list_of_animals: Vec<&Animal> = ...; // or let list_of_animals: Vec<Box<Animal>> = ...; it is frowned upon due for stylistic as well as performance reasons: each method call from here-on-out will be invoked via interface dispatch.
read more →Web-Assembly is a binary execution environment sheparded by major browser vendors in the WC3. Once implemented, web-assembly will be an alternative to Javascript when it comes to programming dynamic clientside applications on the web.
The “assembly” piece of web-assembly is the Virtual Instruction Set Architecture (Virtual-ISA) that webassembly targets. Unlike other instruction set arcitectures (e.g. ARM, x86, Mips), web-assembly’s ISA doesn’t actually map to a specific hardware type
Ok, so web-assembly is an ISA that runs compiled code in your web browser, but it’s not the first to try!
read more →Sums and Products
The Rust and Go programming languages are relatively new programming languages with an emphasis on writing and maintaining very large codebases. Go was designed to be used internally at Google in their internal services and one of the main driving forces behind rust is Servo: a web-browser written from the ground up focusing on layout parallelism and safety.
What I think is really interesting about both is that they decided against using Exceptions as the main method of error handling; (D and Nim are other newish compiled languages that stick with Exceptions).
read more →Turns out it's pretty fast
Problem As a totally contrived example, I will be computing the expression
$$ \sum_{i=0}^{1,000,000,000} \begin{cases} i/2 + 2 & \text{if } i % 2 = 0 \\ 0 & \text{otherwise} \end{cases} $$
in both C and Rust to see how close in performance Rust can get to C while still being written in an idiomatic pure-functional style.
Rust use std::iter::range; fn main() { let mut iterator = range(0i32, 1_000_000_000i32) .filter(|x| *x % 2 == 0) .
read more →