Projects

Unison
Unison screenshot

Unison is a simple, pure functional programming language with one trick: types and terms are content-addressable. As it turns out, this massively simplifies many aspects of programming, especially distributed computing.

I first contributed to Unison for fun, as an outside open-source contributor, and later got hired by the team to work full time, primarily on the core code authoring data structures and algorithms.

You can check out the language here and see a list of my contributions here. Whatever you think of Unison (and you should think good things!), content-addressable ASTs are the way of the future. You'll see, you'll all see!

T Times
T Times screenshot 1 T Times screenshot 2

T Times is a public transit dashboard for riders in the greater Boston area. It combines real-time bus and train data from the MBTA feed with walk-time estimates from the OpenRouteService API to render a dense dashboard with little "leave your current location in X minutes" icons.

The implementation also features some fun geospatial data structures an algorithms, all implemented from scratch: a bounded volume hierarchy, geohashing and un-geohashing, polyline parsing, Ramer-Douglas-Peucker, a polygon containment algorithm, and more. These are to provide features such as contextual location names, like "Routes near you in [neighborhood], [city]".

T Times is a registered 501(c)(3) non-profit. The app is live at ttimes.boston, though it doesn't look like much if you aren't currently near an MBTA stop.

T Times is also currently undergoing a rewrite in Rust (classic)... stay tuned!

ki

ki is a lightweight structured concurrency library in Haskell. I first heard about structured concurrency in a 2018 blog post by Nathaniel J. Smith entitled Notes on structured concurrency, or: Go statement considered harmful. This immediately piqued my interest, as a Haskell enthusiast, because I knew of many ways that spawning Haskell's own green threads, analogous to goroutines, were also "considered harmful" and often misused, leaking resources and leaving background computations running longer than they should. I ported some basic ideas from Trio, the Python implementation of structured concurrency, but in Haskell things look quite different, as there is a runtime, and it supports prompt delivery of exceptions between threads.

ki's implementation is small, but mighty. It uses a careful combination of asynchronous exception masking, transactional memory, and atomic fetch-and-add to guarantee that background threads don't outlive their scope, exceptions propagate from parent to child and vice-versa, and memory and CPU usage remain minimal.

The test suite was also sophisticated, for a time. It used the dejafu library to mock IO and exhaustively enumerate all possible interleavings of threads, which allowed me to confirm no race conditions exist with relatively little effort. I eventually moved to a simpler test suite with individual unit tests, because using dejafu in the test suite either necessitated an undesirable effect on ki's type signatures, or else required the use of a proper module system like Backpack, which adds unwanted complexity.

ki-unlifted

ki-unlifted is a variant of the ki API suitable for monads that are "unliftable" to IO.

Chores
Chores screenshot 1 Chores screenshot 2

Chores is a self-hosted progressive web app for managing a large collection of recurring tasks. I built it after becoming a homeowner in 2024 and spending a week Googling "new homeowner upkeep", ending up with an enormous list of tasks ranging from weekly to every other year, with no good way to track them, combined with an already-large list of household cleaning tasks due every 1-4 days.

The app divides chores into "due today" on the home screen and everything else behind a "view all" page, keeping the clutter down. Chores can be automatically rescheduled from their completion date, or pinned to the calendar with flexible recurrence rules: "every Monday", "every other Friday and Saturday", "every 15th of the month", "every 3rd-to-last day of the month", "every 1st and 3rd Tuesday". Calendar-based chores are uncommon, but handy for trash day, street sweepings, and rent reminders.

Chores are ordered by an invisible "rot" score, which is a measure of how neglected a chore is, as a function of how many days it's overdue relative to how often it's meant to be done. The most neglected chore floats to the top, making it easy to hack away in priority order in the (overwhelmingly likely) case that you don't have time to do them all.

Shopping
Shopping screenshot 1 Shopping screenshot 2

Shopping is a self-hosted grocery list progressive web app with one major distinguishing feature: items can be associated with specific stores, and within each store, a specific aisle or section. While in shopping mode, the list is sorted by section in the order you've configured. The result is a streamlined shopping experience... no more doubling back across the store to pick up that last item or two!

The concurrency model is somewhat novel and works well for this kind of two-users-at-most app. There's no event log, no server-push, and no requirement for fully linearized transactions. Instead, every edit bumps a monotonically-increasing data version. The server accepts client requests regardless of what version the client is at, only rejecting genuinely conflicting operations, such as trying to edit something that's already been deleted. Every response from the server includes the current data version, and if the client finds itself behind, it refreshes everything. Combined with a fetch-on-visibility mechanism (with aggressive caching), this produces a simple system that works really well in practice. I or my spouse can be at the store actively shopping, while the other is at home thinking of items to add at the last minute, and everything just works without requiring manual refreshing.

kll

kll is a library that provides a KLL (Karnin-Lang-Liberty) sketch, a probabilistic data structure used to approximate quantiles. The library also includes a sliding window extension.

t-digest

t-digest is a Unison implementation of the online clustering variant of the t-Digest data structure, as defined in "Computing Extremely Accurate Quantiles Using t-Digests" by Ted Dunning and Otmar Ertl. It's useful for accurate accumulation of rank-based statistics such as quantiles and trimmed means on large datasets, and is especially accurate at very low and very high normalized ranks. It can also be efficiently merged, making it suitable for map-reduce workflows.

t-digest was the first "real" data structure I implemented when exploring efficient solutions for producing online P95 estimates and the like, retaining a minimal number of samples. It works quite well!

t-digest-window

t-digest-window extends the t-digest library with a clever implementation of a sort of sliding window abstraction: the weight of samples decays exponentially, per a fixed time window configured during data structure initialization.

This adaptation offers a significant improvement over the usability of a t-digest in practice, as it's often the case that newer samples are more important than older samples for an unbounded stream of data.

There are other sliding window implementations I experimented with before settling on exponential decay, with different time and space trade-offs.

The main quirk of this idea is that samples don't fall out of the data structure entirely when their age reaches the window duration, as is common with most sliding window abstractions. However, the expected lifetime of a sample is still precisely the window duration, so for many applications, this is totally acceptable.

heaps

heaps is a mergeable heap data structure, as described in G. S. Brodal and C. Okasaki, "Optimal purely functional priority queues," Journal of Functional Programming, 1996, supporting O(1) insert, peek, and union, and O(log n) time pop. The library provides three heap variants: a min heap, a max heap, and a heap that accepts a custom ordering function.

finger-tree

finger-tree is an implementation of the finger tree data structure in Unison, as described in "Finger trees: a simple general-purpose data structure" by Ralf Hinze. In Unison, the finger tree data structure is a little bit awkward, as the monoidal measure dictionary has to be passed manually to the operations that require it, since the language lacks a mechanism for implicit arguments (which isn't necessarily a bad thing). Nonetheless, it's useful to have a blueprint implementation of a general finger tree, which can either be wrapped, or copied and specialized to a particular monoid and measure.

queues

queues is a Haskell library providing two purely functional queue implementations based on Okasaki's work: a real-time persistent queue, and a faster ephemeral variant.

I built and benchmarked several more variants before determining that those two are the best-performing.

The real-time queue implements a technique that Okasaki calls "scheduling" - carefully arranging the data structure to force internal nodes to weak-head normal form ahead of when they are needed, so enqueueing and dequeueing always run in constant time, unlike the classic two-list queue that occasionally exhibits an O(n) rotation during dequeueing. It's genius.

reservoir-sampling

reservoir-sampling is a library that provides a couple of different implementations of reservoir sampling, a technique for selecting exactly k random elements from a stream of unknown size.

quickselect

quickselect is an implementation of the quickselect algorithm, which picks out the kth smallest element of a list in O(n) time. This algorithm is commonly used to select the median of a dataset faster than the naive approach of sorting and then picking the center element.

mit
mit screenshot

mit is a Git wrapper that exposes a small set of high-level commands: commit, sync, branch, and undo. mit commit replaces git commit, mostly dispensing with the staging area by invoking git commit -p under the hood. mit sync acts roughly as git stash && git pull && git stash pop, but considerably smarter.

I built it to streamline my own solo git usage, but also to massively simplify the process of collaborating on a codebase with others, all pushing to a shared branch (think: side project or hackathon).

Imagine you've made a few commits you haven't pushed. Meanwhile, the main branch has advanced. On top of that, you're halfway through something, with a pile of unstaged changes. In vanilla Git, if you decide you want to merge the main branch into yours, you're juggling a stash, a merge, and an unstash, with potential conflicts to resolve during merging, and then again during unstashing. With mit, you just run mit sync.

Run mit with -v and you'll see it invoke the git binary tens of times per command — all sequencing that mit handles quietly on your behalf.

These days, jj seems to be the new hotness in the "Git but better" space, but mit has served as my own open-source replacement for git, papering over its rough edges, for years. :)

Poll Supply
Poll Supply screenshot 1 Poll Supply screenshot 2

Poll Supply is a progressive web app for creating polls with approval voting ballots. I built it to have an easier time deciding what movie to watch or restaurant to eat at, among a small mutually trusted group of friends (trust is necessary, because poll results are visible live!).

The backend is event-sourced and pushes changes to clients, so users only need to load the poll once and don't have to refresh to see the latest poll options or results. The frontend, meanwhile, keeps track of its outstanding requests, and assumes they will all succeed (so that it can update the UI immediately), and separately keeps a source-of-truth model based on the event stream from the server.

Baby Tracker

Baby Tracker screenshot

Baby Tracker is a self-hosted progressive web app for logging newborn feedings, sleep and wake windows, and diaper changes. I built it after my son arrived and I found that every app store option was either too slow to load, cumbersome to use, had useful bits buried behind a paywall, or all of the above. My goal was ultimate simplicity: open app, tap button, close app. I also integrated the backend with push notifications, for reminders and progress updates, delivered to me via a private family Discord server.

trace

trace is a library that lets you annotate arbitrary spans of code with a name, for the purpose of logging how long the code takes to execute. Spans can be nested, forming a tree. I use this library extensively in production to easily identify which parts of a program are taking the most time, in order to prioritize where to look for optimization opportunities. It's also helpful for identifying where parallelism can improve performance.

deflate

deflate is an implementation of the DEFLATE compression algorithm, as specified by RFC 1951.

zipfile

zipfile is an implementation of .ZIP archive parsing.

Park Bench
park-bench screenshot

Park Bench is a quick-and-dirty, low-friction benchmarking tool with immediate feedback. It features live comparisons between different functions under benchmark for a variety of different statistics, including wall-time, CPU time, resident memory usage, allocation speed, and number of garbage collections.

Whenever benchmarking something in Haskell, I reach for Park Bench first. Only very rarely do I find myself wishing for something with more robust statistical analysis, beyond Park Bench's relatively simple two-point linear regression.

benchmark

benchmark is a trimmed-down Unison port of the same idea. It features many fewer statistics, as Unison doesn't currently expose any runtime stats from its runtime.

Cretheus

Cretheus is a clean wrapper around Aeson, Haskell's premiere JSON library. It exposes JSON encoding and decoding combinators, rather than leaning into typeclasses.

I built this interface as an alternative to Aeson, because in practice a typeclass-style API leads to defining and using a lot of "throwaway types" that cause clutter and long compile times. It's also much easier to accidentaly break an API during what feels like a routine refactoring. Sometimes, or maybe most of the time, just writing straightforward, explicit encoding and decoding routines is all you need!

unconditional-jump

unconditional-jump is an implementation of a "jump"-like control flow primitive in Haskell. It lets you define a label within a scope and jump to it with a return value, unwinding the stack, much like a return-statement in an imperative language.

It's often the syntactically cleanest way to implement programs that want to stop computing and return early when any error condition is encountered. Without it, your options in Haskell are to pattern-match and proceed only in one branch, operate in a monad stack that supports throwing errors, or throw an untyped exception, each with their own tradeoffs. I originally implemented this abstraction with the continuation monad, but for performance and ergonomic reasons, reworked it using an exception-based implementation instead.

hasql-listen-notify

hasql-listen-notify is a library that adds Postgres LISTEN/NOTIFY support to the hasql ecosystem.

I built this after discovering that the only other published library purporting to offer this functionality had numerous bugs. hasql-listen-notify properly handles all of the tricky bits, including escaping Postgres identifiers and resetting closed connections in the await loop. It also exposes the backend PID of notifications, which is useful for filtering out one's own published messages, and other diagnostic purposes.

timer-wheel

timer-wheel is a Haskell library providing an alternative timer data structure for applications that need to register timers at scale. GHC's built-in timer manager uses a single global priority search queue, which can become a bottleneck when registering hundreds of thousands of timers. timer-wheel uses a fixed-size array of priority search queues instead, trading some insert and expiry performance for timeout accuracy. It also supports cancelable recurring timers, which re-enqueue themselves after expiring.

repld

repld is a pair of programs that communicate over a Unix socket. The server wraps any long-running stdio-based program, and the client sends input to it. I use a tiny vim keybinding to tie them together, so that sending the "inner paragraph" (vim-speak for the chunk of text under the cursor) to a persistent REPL session is a mere keybinding away.

repld solves the "quadratic replay" problem that plagues traditional terminal REPLs, offering a more declarative notebook-style development workflow instead. In a REPL, if you've sent (say) 5 commands before deciding you want to re-run them all after tweaking some source code, you refresh your session, then press up 5 times, enter, up 4 times, enter, up 3 times... exhausting!

I nearly always have a repld session running during development, especially when the project I'm iterating on is factored well enough to support localized REPL-style iteration.

http-router

http-router is a standalone Haskell HTTP routing library built on WAI. It provides a straightforward DSL for defining a routing table, and compiles to an efficient segment-based lookup tree.

I use this library for every web app backend I write in Haskell. It's so much more lightweight than anything else I've seen, and vastly outperforms the naive linear route lookup you'd get if you try to write a web app without any additional routing abstraction. http-router

http-router is a Unison implementation of a similar library. The core idea is the same: a data structure and set of combinators for writing an efficient HTTP route parser. However, the libraries differ in a couple of fundamental ways per the semantics of the programming languages.

termbox

termbox is a high-level Haskell FFI binding to termbox, a minimal C library for writing terminal user interfaces. I found termbox to be a delightfully simple alternative to something like ncurses, and the other bespoke TUI libraries in the Haskell ecosystem. It's bare-bones, which is great for making little games and simple programs, but less great for making sophisticated dashboards of widgets. I built termbox atop two lower-level layers, for modularity and code reuse, and also built two higher-level wrappers that expose the imperative termbox API as something more purely-functional.

termbox-bindings-hs

Low-level bindings.

termbox-bindings-c

Even lower-level bindings.

termbox-banana

An FRP flavored wrapper around the termbox API.

termbox-elm

An Elm Architecture flavored wrapper around the termbox API.

jsonapi

jsonapi is an implementation of JSON:API v1.1, a specification for building APIs in JSON.

crc32

crc32 is an implementation of the CRC-32 checksum algorithm, as used in Ethernet, PKZIP, PNG, and more.

bounded-recent-set

bounded-recent-set is a data structure similar to an LRU cache. It is a fixed-size set that tracks the logical insertion (or re-insertion) time of every element. If a new element needs to be inserted when the data structure is at capacity, the oldest element is evicted.

I implemented this data structure to power the "recent routes" feature of T Times, the public transit dashboard app I authored. Each user has their own bounded recent set of bus and train route/stop pairs, which simply tracks the latest 50 unique routes the user rode, at the stop they boarded. Then, in the UI, the set is filtered down to only those that are nearby (up to 4).

This feature is my completely hands-off replacement for a contextual "favorite routes" feature, dependent on the user's current location. It works great!

tasty-hspec

tasty-hspec is a small utility library that lets you run an hspec test suite under tasty without manually converting each test. For a period when both libraries were under active development and users were migrating from one to the other, it served as a convenient bridge between the two ecosystems.

int-supply

int-supply is a minimal Haskell library for generating unique integers using atomic fetch-and-add.

list-shuffle

list-shuffle is a Haskell library for shuffling and sampling lists with optimal time and space complexity, using the Fisher-Yates algorithm internally. There are a lot of cute purely-functional implementations of list shuffle available, but none of them even come close to the performance of some good old-fashioned (internal) mutability :) shuffle

shuffle is a Unison port of the same idea.

percent-encoding

percent-encoding is an implementation of the percent-decoding algorithm, which converts a URL-safe string into a string that can contain any Unicode code point. It assumes the string is encoded in UTF-8.

text-ansi

text-ansi is a lightweight Haskell library providing combinators for decorating text with ANSI escape sequences. It supports common textual types and uses GHC rewrite rules to minimize the memory and CPU overhead of inserting the escape sequences.

http-media-type

http-media-type is an HTTP media type data structure, parser, and renderer, as specified in RFC 9110.

strict-tuple

strict-tuple provides types and typeclass instances for strict tuples in Haskell, filling a gap in the standard library.

pg
pg screenshot 1 pg screenshot 2

pg is a command-line utility knife for Postgres, with a few features that simplify the ceremony of initializing a cluster, creating a database, and so on, all scoped to the current directory for project-local Postgres access.

I built pg because I often have many projects on my filesystem that talk to Postgres, and it's convenient to sandbox each one to its own database cluster. The binaries that Postgres ships, however, are optimized for running just once on a machine, like a 1990s sysadmin, setting up a global Postgres installation in system directories.

pg also includes a query plan pretty-printer for investigating query performance. Full-featured online visualizers exist, of course, but sometimes all you need is flat text in a terminal, and this output format fills a nice middle ground between raw EXPLAIN output and a full HTML canvas.

stm-pubsub

stm-pubsub is an implementation of the publish-subscribe pattern built on top of Haskell's Software Transactional Memory (STM). It's similar to a "broadcast channel" abstraction, but with the added feature that slow subscribers can cause the publisher to block, as a backpressure mechanism.

mbta

mbta is a partial set of bindings to the MBTA V3 API, including predictions and alerts.

riak2

riak2 is a nearly-complete set of low- and high-level Riak bindings, leveraging many features of the Haskell type system to expose a safe and ergonomic API. The bindings cover Riak's key-value store (including sibling resolution), CRDTs, secondary indexes, map-reduce, bucket types and bucket properties, Erlang functions, and search.

I'm also a contributor to the riak library that precedes riak2. riak-admin

riak-admin is library for programmatically interacting with the riak-admin CLI. I wrote it to supplement direct Riak API access, since Riak's API doesn't cover everything riak-admin can do.

Haskell Papers
Haskell Papers screenshot

Haskell Papers is a collection of computer science papers related to Haskell, functional programming, and similar topics, hosted as a static site on GitHub Pages.

Each paper is tagged with metadata (authors, year of publication), and the collection is filterable on this metadata.

ersatz-pointer

ersatz-pointer is my attempt at a beginner-friendly wrapper around GHC's weak pointer API. The standard interface is quite confusing. The main contribution here is good documentation, though the interface also adds a Source type class to prevent common pitfalls, and adds a Material phantom type to prevent finalization from firing too early.

Pingplot
Pingplot screenshot

Pingplot is a terminal program that pings 8.8.8.8 every quarter-second and renders a live histogram of ping times in a TUI, with support for zooming in and out. I run it whenever I find myself thinking "is my Internet crapping out? Yes... yes it seems to be..."

sqlit

sqlit began as a high-level Haskell binding library to SQLite. Working on it revealed lower-level gaps in the ecosystem, so development has paused while I work on sqlite-bindings and a sqlite-syntax.

sqlite-bindings

sqlite-bindings are fully-faithful 1:1 Haskell binding to SQLite 3, structured as two layers: sqlite-bindings-c for direct C-flavored FFI bindings, and sqlite-bindings for a slightly more idiomatic (but still nearly 1:1) Haskell interface on top.

sqlite-syntax

sqlite-syntax is a work-in-progress parser and pretty-printer for the SQLite flavor of SQL. The goal is to be able to parse and manipulate SQLite queries programmatically, serving as the foundation for powerful Haskell-SQLite integration.

zmq

zmq is an experimental high-level Haskell binding to ZeroMQ, featuring safety improvements over the C++ API. It leverages the type system and carefully designed exposed API to rule out some common gotchas.

libzmq

libzmq is a set of Haskell FFI bindings to ZeroMQ, including draft API support. It exposes the full C API, with the package version tracking the underlying ZeroMQ version directly.

Learn By Reading
Learn by Reading screenshot 1 Learn by Reading screenshot 2

Learn By Reading is a mobile-only prototype of a Spanish learning app. It presents one sentence of a story at a time, with Kindle-like controls for flipping pages: short-press the left or right side of the screen to go back or forward. Long-press on the right side before advancing to reveal the translation.

I found this a fantastic and motivating way to learn: early on you're long-pressing every sentence, but over time you find yourself short-pressing more and more, just reading a book in Spanish.

7 Little Words
Seven Little Words screenshot

7 Little Words is an implementation of the 7 Little Words phone app, but with a custom word bank of English SAT vocab words. I built it because I loved the idea behind 7 Little Words, but felt it missed the mark a bit with its word bank of simple words. Why not have fun and expand your vocabulary at the same time?

Palabritas
Palabritas screenshot

Palabritas is a prototype Spanish vocab practice app modeled after the mobile game 7 Little Words. It presents a few English definitions alongside a collection of 3-4 letter tiles ("palabritas") that collectively spell the Spanish words for those definitions. The goal is to use all the tiles, which advances the board to a more difficult level.

Explore Core and More
Explore Core and More screenshot

Explore Core and More is a tool that exposes an experimental alternative syntax for GHC Core, built primarily for performance analysis and investigation of compiled Haskell code. The basic idea is simple: make Core more readable. One of the biggest wins is rendering state-token-passing style code as straight-line, do-notation-like syntax rather than the deeply nested form GHC normally produces.

It's not the most principled implementation. For starters, it parses GHC's stringy Core output directly, rather than hooking into the compilation pipeline at some earlier, pre-rendering phase. But it's easier to write a parser than to integrate with the GHC API, so I pursued this approach instead. It's serviceable. :)

pywatch
pywatch screenshot

pywatch is a file-watcher utility for LeetCode-style coding sessions. Any time a .py file is touched, it's executed. Minor niceties: debouncing, screen clearing, and a timer in the corner.

ytcd

ytcd (YouTube channel downloader) is a minimalist C codebase that downloads the latest videos from a configured list of YouTube channels. It's built on yt-dlp, runs on a daily schedule, and is organized to drop videos directly into a Jellyfin-compatible directory structure (though users are encouraged to fork the tiny codebase and tweak it to their needs).

Downloads are intentionally delayed by two days, giving SponsorBlock annotations time to accumulate, so that yt-dlp (via ffmpeg) can strip out annoying ad-reads and other promotional segments.

Somerville Candidate Questionnaire 2025
Somerville Candidate Questionnaire 2025 screenshot

Somerville Candidate Questionnaire 2025 is a "grader app" for local politicians' answers to questionnaires ahead of the 2025 mayoral and city council elections in Somerville, Massachusetts. Users could read anonymized responses to each question, grade the answers, and then reveal which candidates they agreed with most. It was a one-off app for a specific election cycle. The link may go offline at some point as I don't plan to renew the domain.

safe-exceptions-checked

safe-exceptions-checked is a small Haskell library based on Edsko de Vries and Adam Gundry's "Lightweight Checked Exceptions in Haskell" blog post. I thought the idea was rather elegant, and the only thing missing was a companion library for others to use. Well, I wrote that, and soon after realized that the abstraction doesn't really make sense in the context of concurrent programming. I abandoned the library after this realization.

language-lua2

language-lua2 is a parser and pretty-printer for Lua, built to experiment with the Earley parsing algorithm. Earley parsers let you define a grammar at a high level, including left-recursive rules, without the careful refactoring that parser combinators require to avoid infinite loops. In practice, the library ended up slow, and I lost interest before getting around to tuning it for performance.

inotify

inotify is bindings to the Linux inotify API for watching filesystem events.

blake3

blake3 is Haskell FFI bindings to the BLAKE3 cryptographic hash function, bundling the hand-optimized C and assembly implementations for AVX2, AVX-512, SSE2, and SSE4.1.

reactive-banana-extras

reactive-banana-extras is an add-on package to reactive-banana, a functional reactive programming (FRP) library. It features a type class that unifies the concepts of Behavior, Moment, and Dynamic (a new type defined as a Behavior paired with the Event that updates it). It also includes a large number of combinators I found useful for writing FRP programs.

wai-middleware-travisci

wai-middleware-travisci is a WAI middleware for authenticating webhook payloads from Travis CI. I first built the functionality directly into one web app, then extracted it as a library the moment I needed the exact same logic in a second place. I don't think anyone uses Travis CI anymore, but hey, the code might still work. :)

proem

proem is a custom Haskell prelude.

Roots

Roots is a work-in-progress batteries-included standard library for Elm, which includes a couple novel abstractions for defining reusable fragments of an update function.

ghc-switch

ghc-switch is a shell script that simplifies the installation and switching between multiple GHC versions.

deterministic-hls-builds

deterministic-hls-builds was an early attempt at shell-scripting a deterministic installation of Haskell Language Server, to avoid ending up with slightly different setups on different machines due to the official installer (or lack thereof). These days, ghcup is a much better solution. :)

Both were primitive tools that were necessary for a time early in Haskell's life, before ghcup was created and deprecated them both.

Note: I am the co-maintainer of these libraries, not the original author.

hasql-interpolate

hasql-interpolate is a QuasiQuoter for hasql that lets you write SQL with interpolated Haskell expressions and spliced SQL snippets, instead of managing positional parameters by hand. It makes SQL queries invoked via a Haskell program vastly more readable.

stm-fsifo

stm-fsifo ("first-still-in-first-out") is a variant of an STM queue that supports constant time removal of any element, not just the front. Its primary use case is a cancelable task queues, and was built to support a (yet unreleased) high-performance resource pool library.

Experiments

Needless to say, not everything I work on turns out great, or turns out at all. These are some of the smaller libraries and apps I have worked on to test out an idea, learn a new library or programming technique, or simply have fun.

Alicia Banana

Alicia Banana is a terminal piano, written with FRP. It turns your keyboard into a piano. The piano is hard to play and doesn't sound very good, but it was fun to build.

Big Joe

Big Joe is a tiny implementation of an efficient logging abstraction. A multicore program often has one global logging thread, which can induce a lot of context switching when log messages are produced from many other threads. Big Joe tries something simple instead: spawn one logging thread per core, and expose a logging abstraction that always routes messages to the core-local logger. I didn't pursue the idea very far, but I think it's solid and intend to flesh it out more. Why is it called Big Joe? I have no idea. It's probably somewhere between a throwaway codename and the beginnings of a full-on brand with an animatronic Chuck E. Cheese licensed mascot, Big Joe the Logging Abstraction, playing the washboard in the back.

Boston Bot

Boston Bot is a Slack bot built for an old work Slack instance. It only ever got one feature before being decommissioned: randomly selecting a movie for the team to watch in the office. I built it as an excuse to play around with a then-new effect framework called fused-effects.

Boston Haskell Arcade

Boston Haskell Arcade is a dorky terminal game platform built during in-person functional programming meetups in the Boston area. We were all playing around with writing terminal games in two distinct styles: the Elm architecture and functional reactive programming (FRP). None of the games are fun at all.

containers-focus

containers-focus is a bridge between two Haskell libraries, containers and focus.

coop

coop is a client and server for cooperatively debugging something with a friend in gdb (or similar), without having to share a screen and keyboard.

daffy

daffy is a horrendously-named Haskell performance investigation framework. It never quite came together, but the vision was a local web app for generating runtime statistics reports and flamegraphs for Haskell programs built with profiling support.

dhall-stylish-haskell

dhall-stylish-haskell is a collection of Dhall expressions for generating a stylish-haskell config file.

earsec

earsec is a parser combinator library for Erlang.

elm-interface

elm-interface is a utility library for simplifying communication between a Haskell backend and an Elm frontend.

elm-codegen

elm-codegen is a library for constructing Elm types from Haskell types.

fast-murmurhash3

fast-murmurhash3 is a pure Haskell implementation of MurmurHash3.

fe

fe is a toy text editor, written with FRP.

gam

gam is a prototype of a purely functional rendering abstraction built on top of SDL2.

h

h is a "what if you could use Haskell expressions instead of bash" project. It uses the GHC API to parse and evaluate Haskell code provided as string input. Not the most sophisticated implementation, but it works well enough and kept me entertained for a few days.

haskell-erlang-bridge

haskell-erlang-bridge is a library for communicating with the Erlang Port Mapper Daemon (EPMD) from a Haskell process.

Hoglet

Hoglet is a simplification of the hedgehog property-based testing library.

hs

hs is a small custom build and development tool that wraps other tools to provide a high-level, unified interface for common Haskell dev tasks: building and formatting code, linting, running automated refactorings, and generating CI yaml.

hspolls

hspolls is a web app for creating and answering multi-question polls, with authentication via GitHub OAuth. It supports subscribing to new poll events via email.

It's Raining Letters

It's Raining Letters is an FRP typing speed game. I built it to practice typing on alternative keyboard layouts like Dvorak and Colemak, before deciding that QWERTY is the way.

java-apache-lucene

java-apache-lucene is a mostly-complete Haskell binding to the Apache Lucene Core API, featuring some clever uses of the type system to model Java's inheritance hierarchy accurately.

json-validation

json-validation is a library for validating the structure of a JSON value. It lets you define a schema using a small DSL of combinators, then check that schema against any JSON value.

kcalcounter

kcalcounter is a simple calorie-counting Android app.

lambdachat

lambdachat is an encrypted chat client and server, made to play around with fused-effects, an extensible effects library.

libh2na

libh2na is a small wrapper around a production-grade cryptography library that aggressively simplifies the API to maximize readability and grok-ability. I built it primarily to learn how cryptographic primitives fit together, and what can be accomplished with a little bit of crypto knowledge.

libnng

libnng provides both low- and high-level Haskell bindings to NNG (nanomsg-next-gen), a brokerless messaging framework.

llint

llint is a Lua linter and static analysis tool, built as an exercise in "datatype-generic programming" as popularized by the uniplate library.

Kerchief

A command-line implementation of the SuperMemo 2 spaced repetition algorithm, for terminal-based flashcard study.

micro-json-grammar

micro-json-grammar is an implementation of a JSON "grammar", which (in this library) refers to an invertible mapping between two types. This technique lets you define a JSON codec for a type just once, rather than separately defining a serializer and deserializer that must be kept in sync.

microcli

microcli is a stab at an ultra-minimalist library for defining command-line options. I honestly can't remember how successful this endeavor was, but however well it worked, I never published it.

mwr

mwr is a bash script wrapper around Haskell's two competing build tools, cabal and stack. It was also an opportunity to paper over some of cabal's notoriously poor UX with relatively little effort.

otp

otp is an implementation of Erlang-style supervisor and worker actors. A supervisor oversees workers and restarts them if they fail, unless their failure rate exceeds a threshold. If it does, the supervisor stops all workers and crashes loudly.

python-parser

python-parser is a Python parser implemented using the Alex and Happy lexer and parser generator toolchain.

reddit-cli

reddit-cli is a terminal-based Reddit client built with the Brick UI library.

refactored-banana

refactored-banana is an aggressively refactored and simplified version of the reactive-banana codebase, undertaken to better understand its implementation.

Second Look

Second Look is a GitHub post-receive hook that emails tagged developers. It was useful for a time and fun to build, but was quickly surpassed by platform improvements.

sessions

sessions is an implementation of session types, as described in the paper "Haskell Session Types with (Almost) No Class".

shamir

shamir is an implementation of Shamir's Secret Sharing algorithm. Take any secret, encode it into N fragments, any K of which can be used to reconstruct the secret. I think every programmer who comes across this beautiful idea feels a compulsion to implement it from scratch. I did, and then moved on, never having had a need for it. :)

sss

I reimplemented the codebase a year later and called it sss, which supported streaming encryption and decryption and had a command-line interface.

simpanel

simpanel is a "dev task dashboard" TUI built for private usage at an old job. It provided a small clickable UI for executing and orchestrating mundane dev tasks, such as grabbing the latest sample database from a staging environment for local query testing and optimization.

Slacky

Slacky was a clever Slack integration for the terminal that didn't take over the foreground. A server component forwarded messages between Slack and connected clients; a client component ran automatically every time the shell prompt rendered. The result was an IRC-like experience where messages appeared in between runs of shell commands. Slack in your terminal, without giving up your terminal.

sloch

sloch is a source-lines-of-code counter for estimating codebase size, ignoring whitespace and comments. Everyone's got to build one of these at some point, right?

Somerville Neighbors

Somerville Neighbors is a local email relay app for Somerville, MA. Users register their email address alongside their home address, which is kept hidden from other users. Emails sent to the site are automatically forwarded to all other registered users within a fixed radius of the sender's location. The idea is a lightweight way to communicate with your actual neighbors: announcing a block party, asking if anyone has extra room in their trash bin this week, or borrowing a cup of sugar.

ssh-tunnel

ssh-tunnelis a tiny wrapper around ssh -N, with help text and argument order that I found easier to remember. With ssh -N, when forwarding from local to remote or vice versa, the remote host always comes last, even though it's logically part of the remote address.

So, using LI for local interface, LP for local port, RH for remote host, RI for remote interface, and RP for remote port, ssh -N -L LI:LP:RI:RP RH becomes ssh-tunnel LI:LP RH:RI:RP, and ssh -N -R RI:RP:LI:LP RH becomes ssh-tunnel RH:RI:RP LI:LP. We use argument order rather than -L/-R to indicate the direction of the tunnel, and we prefix the remote interface and port with the remote host. Yay consistency! Yay simplicity!

Star Realms

Star Realms is a terminal implementation of the Star Realms card game.

streaming-histograms

streaming-histograms was an early attempt at an elegant abstraction for producing a relatively accurate histogram for a large dataset, without naively retaining every sample ever observed. I eventually revisited this idea and authored a couple of Unison libraries for the T-Digest and KLL data structures, which are each far more clever than anything I could have invented on my own. (Well, KLL is actually particularly simple, but the mathematics that justify its error bounds are not.)

Subpross

Subpross is an experimental subprocess runner that intends to capture the "essence" of a subprocess in the Haskell type system.

synchronized

synchronized is a small Haskell utility that protects a block of code from running on more than N threads at the same time. A classic example is logging to the terminal, where naive concurrent writes to stdout can cause garbled output. Another example is bounding the number of live worker threads with a semaphore, putting an upper bound on concurrency and resource usage no matter how much work there is to do.

task

task is a small library for running processes in parallel.

Warpless

Warpless is an aggressive refactoring of the warp web server. My primary goal was to understand the web server and simplify its internals to a point where outside contributions became much more frequent. I lost a bit of steam on it :)

xmonad-keys-qq

xmonad-keys-qq was born out of fascination with compile-time metaprogramming: the idea that instead of writing code directly, you can write something that turns into code when the compiler runs, as a sort of pre-processing step. Looking back, it's hardly doing anything: just giving a slightly nicer syntax for creating a tuple with a string as its first element. But at the time, optimizing my XMonad configs for readability was a high priority.

zzz

zzz is a high-level algebraic effects interface to Microsoft's Z3 theorem prover. It exposes a DSL for declaring variables, asserting constraints, and checking satisfiability.