Most of my personal writing lives at Here lie posts of the more technical variety, usually about Ink, Oak, or the projects I’ve built with it.

Optimizing the Oak compiler for 30% smaller, 40% faster bundles

This blog post originally appears on the Oak Blog. It’s been copied here, because when this blog went up, the Oak blog wasn’t quite ready for primetime.

Behind the scenes: building the Ink codebase browser

The Ink Codebase Browser is a refined tool for exploring open-source projects on GitHub. Compared to the experience of clicking through file hierarchies and previews on GitHub’s website, this project aims to provide a much better “browsing” experience for online codebases on GitHub with a file tree, rich Markdown and image previews, and multi-pane multi-tab layouts.

Ink playground: the magic of self-hosting a compiler on JavaScript

The Ink playground, named project “Maverick”, is a web IDE and REPL for Ink. It’s a single-page web application written in pure Ink, and makes it possible to write and run Ink programs entirely in the browser.

Eliza: an isomorphic Ink app for web and native

Last month, I launched Eliza, a chatbot modeled after the classic MIT conversational program and written entirely in Ink. Though the project itself isn’t novel or interesting – it’s mostly a port of existing implementations of ELIZA – Eliza is built as an isomorphic Ink application, meaning a substantial part of the codebase can run both natively, on a server, and on the client (a Web browser).

Assembler in Ink, Part II: x86 assembly, instruction encoding, and debugging symbols

This is the sequel to Assembler in Ink, Part I where I started documenting my process of building an x86 assembler in Ink. In Part I, we looked at the high-level jobs of an assembler, and how August constructs an ELF file that an operating system (specifically Linux here) could understand and turn into a process.

Assembler in Ink, Part I: processes, assembly, and ELF files

Over the holidays, I decided to learn about the lower level components of programs by writing an assembler and linker from scratch. Assembly and linking are two of the last steps of a typical “compile” process that generates an executable file from an assembly program.

Taming infinities: adding tail call elimination to Ink runtimes

Ink is a mostly functional programming language, and Ink programs express iteration through recursion. Usually, this kind of recursion is hidden behind higher level library functions like map and each.

Implementing the lambda calculus in Ink

The lambda calculus is a formal model of computation, a mathematically rigorous way of thinking about what computers do. Unlike the other popular theoretical model, the Turing machine, the lambda calculus describes all computation in terms of pure functions, and functions acting on other functions.

BMP: the simple, underappreciated image file format

In the early days of Ink, the most interesting thing Ink programs could do was take some textual input, and output some text back to the terminal.

Macro elegance: the magical simplicity of Lisp macros

Lisp is a homoiconic programming language – Lisp program source code is also a first-class data structure in Lisp, made of nested lists of symbols.

A retrospective on toy programming language design mistakes

I’ve written a few toy programming languages, mostly of the functional paradigm. The most significant of those is Ink, but I’ve also written a Lisp-style mini-language called Xin, and now a proper Lisp in Klisp.

Nightvale: an interactive, literate programming notebook built on Ink

Building on my progress and positive experience with Klisp, I recently created Nightvale, an interactive notebook in the browser for literate programming and communicating computational ideas using Klisp code.

Klisp: a Lisp in about 200 lines of Ink

Klisp (named after inK LISP) is a very minimal Lisp environment with a core written in about 200 lines of Ink. In addition to the interpreter itself, Klisp also includes an interactive repl and a small standard library that makes operations on lists and Klisp values easy and idiomatic.

Weighing software abstractions to design better programs

I like thinking about software as if it were matter, following some pre-ordained laws of nature as if they occupied real space and time. Of course, the metaphor often only stretches so far, but I think metaphors of physics in software can give us great mental models for thinking about the complexity that we create when we build software, which are the most complex machines humans design.

Histools: visualizing my browser history over time with Ink and Torus

Today I made Histools, a small set of tools for visualizing browser history data from Apple’s Safari browser. It renders a heatmap of pages visited on Safari over time, alongside a searchable, sorted list of pages I’ve visited most often with mini-heatmaps for each URL.

Schrift: a faster, bytecode-driven interpreter for Ink

I’ve been working on a new big project recently: a faster, better-designed, more versatile interpreter for Ink, rewritten from the ground-up, called Schrift. Schrift is an experimental runtime for Ink focused on performance and runtime instrumentation capabilities, and is still very much under development.

System calls from the Go runtime in the Minimum Viable Go Program

Go, despite being a fully compiled language, has a sizeable runtime that helps Go programs handle things like multithreading, input/output, global variable initialization, and memory safety.

Ink language support in Visual Studio Code

Today, I published the first version of ink-vscode, which adds support for the Ink language to the Visual Studio Code editor. So far, there has only been one kind of editor support for the Ink language, in the form of a syntax definition for the Vim editor.

Syntax highlighting Ink programs with the September toolchain

Although Ink is over a year old now, it has never had a dedicated syntax highlighter. When I write Ink programs, which is the vast majority of my time reading Ink code, I’ve used a vim syntax file to take advantage of vim’s syntax highlighting capabilities.

The September compiler: translating Ink to JavaScript

September is an Ink to JavaScript compiler, written in Ink itself. It’s so-called because it’s the first in a forthcoming series of autumn-month-themed tools written in and for Ink:

Scale-free software

Good software engineering is concerned with two kinds of scale: operational scale and engineering scale. Operational scale measures how many processors and compute nodes are in your production infrastructure, and how many requests and responses the system handles every second.

A discussion on NLP, GPT-3, and language models

Preface Last Saturday, I hosted a small casual hangout discussing recent developments in NLP, focusing on OpenAI’s new GPT-3 language model. Not being in the machine learning field, I wanted to understand what the excitement was about, and what these new language models enabled us to build.

Better terminal output from Ink with ANSI escape codes

ANSI escape codes Most of the time, we think of a computer terminal as a place to output text. We generate logs and print output from programs to the terminal, and interact with the shell by typing lines in and getting lines out.

Binary search for rational approximations of irrational numbers

What’s a reasonably simple rational approximation of Pi? We might take a naive approach and simply take a fraction like \(\frac{314159265}{100000000}\) and reduce it to get a fractional representation of an arbitrary decimal form of Pi.

Notable papers about computing and software

This year, I’ve been spending more time reading papers about computer science and software engineering. I’m not in academia, so I don’t always read papers in the cutting edge of the field, but I’ve enjoyed reading seminal papers written at the birth of interesting technologies.

Traceur: a path tracing renderer in Ink and JavaScript

Traceur (pronounced like trace + connoisseur) is a path tracing renderer written in Ink. Traceur is capable of rendering scenes with spherical objects, realistic shadows, reflections, refractions, and depth of field.

inkfmt: a self-hosting code formatter for Ink

inkfmt (pronounced “ink format” or sometimes “ink fuh-mt”) is a self-hosting code formatter for the Ink language. This means inkfmt takes valid Ink programs and normalizes the formatting of the code to be readable and clean.

How I set up my servers

Many of my projects include a web server, usually written in Go, Node.js, or Ink. I deploy these servers to Linux VMs running on DigitalOcean, and I set them all up very similarly.

Computing pi as a Riemann sum

While researching the difference between Intel’s various x86 SIMD extensions, I came across this article that demonstrates SSE and AVX performance differences using an algorithm to compute an approximation of pi using a Riemann sum under a curve.

Things I'm learning about in sales

(This is an archived copy of a post originally published at As I’m diving deeper into my role at Hack Club Bank, I’m trying to learn more about sales and working with customers, and I’m also learning a lot every week about leading a B2B product.

Thank you, Hello Hack Club

(This is an archived copy of a post originally published at Summer’s almost over! It’s a change of season, and the season of changes.

Visualizing and exploring sorting algorithms in two dimensions with Ink

Until Elon Musk brings his Neuralink gadgets to market, our eyes are the highest-bandwidth way we have of understanding the world around us. We can look at something and immediately take in the hues, the lightness and the darkness, the shapes, and most importantly, the patterns that we wouldn’t be able to notice if we couldn’t use our vision.

How I side project

(This is an archived copy of a post originally published at This post started out as a long-form response to this tweet by Raj Kunkolienkar: