There are a collection of notes that I've written while learning something new or working on a project outside of my comfort zone. I find writing them helps me understand why and how some code works. The ones here vary in quality, but if you've found them, I hope they can help you like they helped me. Good luck!
I'm a big fan of unit tests for self-contained and math-heavy functions, with statistics code being a big example. If you write code to calculate pvalues or run a hypothesis test for a novel setting, you should also test it. Here are some tips on writing those inherently flakey tests.
Getting started with tree-sitter can be hard: it's a super powerful code parsing library, but takes a bit to get going. These are my notes to get a small program off the ground to read and query a syntax tree.
Rust's proc macros are a powerful, but complicated, way to implement traits. When done well, you can just derive traits on any eligible struct you want! These are my notes getting started with proc macros for deriving traits and some of the traps to avoid.
Optimizing an action for speed isn't just a calculation comparing the speedup versus how many times you do the thing. That view assumes that the number of times is fixed, but speed can unlock whole new ways of working!
CUPED, a core part of causal inference at tech companies, sounds unfamiliar to economists at first, but is really just a basic regression concept. Here's a quick introduction to what CUPED is, how it boils down to regressions, and what's unique about CUPED if not the math.
Writing tests in Rust is moderately different from writing them in Python. That's probably not shocking, given how different the two languages are. Here's my notes on getting started with Rust testing, coming from a Python testing background.
I dug up some of my favorite examples from Chris Sims's class of what can go wrong with confidence intervals. We all know that we can't interpret them as a statement about post-sample or posterior uncertainty, and he had some fun cases where confidence intervals were clearly wacky.
Want to write your own functional language server? Here's the bare minimum needed for a language server to provide syntax highlighting through semantic tokens, usable in any modern editor or IDE. Performance isn't great, but hey, it works!
Just a weird public service announcement that .gitignore files are strict about comments. The # has to come first, otherwise it matches files. No leading whitespace, no inline comments.
This note looks under the hood of polars dataframes, where data is stored in the Apache Arrow format as an array of data chunks. These chunks connect to polars threading and caching, so operations on the same data can take vastly different amounts of time depending on how many chunks are used.
It's hard to write notes on statistical analysis and data reconfiguration without well-rendered math! Here's how I set up LaTeX web rendering through KaTeX, including copy support and LaTeX environments.
I've always hated setting up virtual environments as part of my Makefiles. Now, with uv, I don't have to worry about whether my virtual environment is up to date with my dependency list. There's just one missing link in clean Makefiles: rebuilding Python targets when those dependencies change.
Following up my earlier note on Python, you also need to be careful with terminal settings when building text user interfaces in Rust. Do things wrong and your terminal will be all messed up even after your program exits. Here's a trick to avoid that problem when using Crossterm.
There's a great crate for using the Language Server Protocol (LSP) in Rust, but there's not much documentation on how to use it. These are my notes on getting a basic lifecycle communication with a language server.
I frequently use git's pre-commit hook, but wondered about the others. Here, I explored a much less useful hook that can edit commit messages after you enter them. It's fun for jokes, but I'd never want that hook making changes in anything important!
I think it's common knowledge now that using pip for Python package management can go off the rails quickly and break things. I never ran into the worst problems myself, so I constructed my own package index to force the failures and see them firsthand.
The Language Server Protocol (LSP) enables a lot of my favorite features by letting editors communicate with a common language server. I wanted to learn more about how it all worked, so I communicated with a language server by hand, just typing text into the terminal.
When writing a text user interface, it's easy to mess up the terminal settings that persist after your program exits. If things go really wrong, your terminal can end up practically unusable! I have some tips to avoid those outcomes when building in Python.
I challenged myself to do Advent of Code this year using only polars, which meant I could only read the weird input files using readers meant for tabular data formats! These are my tricks for making CSV readers interpret all sorts of other inputs.
A big selling point for polars is its Rust implementation: Rust is way faster than Python, and that time adds up when processing a lot of data! With plugins, you can fill the gap when polars doesn't have a fast implementation of some function on your data. Write in Rust, call from Python.
I was surprised that it's not that hard to get Rust code running on AVR microcontrollers. You can usually use a premade template, but I dove into the configurations to see how it all worked.