All my projects (2008-2023)

It might be a “getting old[-er]” thing, but I’ve recently started feeling like documenting the complete set of software projects I’ve worked on that I remember. Not as a CV (an advertisement of paid work), but a comprehensive list of everything.

I’m done for now for 2008-2023. I filled out all the headings of my projects with blank bodies. I started with the old stuff and continuously made updates a little bit per day. After a month I was done. At somepoint I was saying “oh for god sake, there’s still more left”, which, if I may boast a little, indicates I did a lot of things over the years.

Some of these projects are trivial, frivolous, very dubious, and some of them are genuinely interesting, novel, or high quality. But it’s all me.

Table of Contents

2023

copy-paste-sync

I wrote this trivial tool called copy-paste-sync that can copy/paste between systems by always keeping the clipboard in sync. It basically just watches the clipboard for changes and then POSTs the content to interested parties. At work I use a MacBook, but I also have my Linux laptop next to it, so being able to copy/paste between the two is handy.

hell

Hell is a shell scripting language that is a tiny dialect of Haskell that I wrote for my own shell scripting purposes. Full blog post about it here.

2022

envy

I found myself using tools that want to control my shell environment at work in order to run commands properly. This makes it annoying to simply run a command from Emacs. So I wrote a mini tool called envy that simply saves the environment generated by such a tooling setup, and then execute any command with the same environment later.

2021

proclog

While consulting on a project that ran executables deeply within it, I wrote proclog as a kind of ‘smarter tee’. I haven’t used this for a while and it isn’t maintained anymore, but it was handy in the moment.

lexx

I wrote a project called lexx, which lexes Haskell code, specifically Show instances, but it can handle fairly unstructured input, and still pretty print it with colours nicely. It’s good for dev logs or general pretty printers.

hag

I fiddled about with a project called hag, “Haskell ag”, which would let one “grep” Haskell files for identifiers, and exclude strings, comments, etc. by lexing them properly. I haven’t used this for a while, it’s currently in the freezer.

2020

inflex

This was my dream project that I planned on being The Big One for my 30s. It involves all my skills: web, services, parsers, type checkers, interpreters, UI, etc. I had a business, a registered trademark, lawyers draft up Ts&Cs and a privacy policy, accountant, Stripe account, etc. It was going to be an online spreadsheet competitor. Inflex was going to be a big hit.

I had a kid and then it took a back seat, I couldn’t financially justify paying an accountant and for all the services when I only had an hour a week to dabble in it. So I packed it in.

However, it has some of my best work. The compiler pipeline is beautiful. Some of the implementation is wonderful. The design trade-offs are brilliant and I researched everything over 2 years. The archive repo is here.

2019

novella

For some bizarre reason, I thought it would be a good idea to make a structured editor in the terminal called novella: the big idea was to define a simple grammar for any language and get a structured editor out of it, like this:

grammar :: Grammar
grammar = $(checkGrammar $ runDefine $ mdo
  -- General expression
  expression       <- rule "Expression" (ChoiceSchema [variable, constructor, parentheses
                                                      ,tuple, let', application, string])
  application      <- rule "Application" (CompositeSchema [expression, expression])
  parentheses      <- rule "Parentheses" (CompositeSchema [openParenSchema, expression, closeParenSchema])
  -- Tuple
  tuple            <- rule "Tuple" (CompositeSchema [openParenSchema, tupleElements, closeParenSchema])
  tupleElements    <- rule "Tuple elements" (ListSchema expression ",")
  -- Identifiers
  variable         <- rule "Variable" (IdentifierSchema "Variable")
  constructor      <- rule "Constructor" (IdentifierSchema "Constructor")

streaming-parsers

I wrote, along with Michael Snoyman, some streaming JSON/YAML parsers, in a package I called streaming-parsers, with the express intent to avoid security issues implied by packages like aeson which consume the whole input given by the user. This package never got used, but I did end up using reparsec elsewhere, which was like a parsec that streams like attoparsec, but works on any token rather than Text/ByteString. Arguably megaparsec fits that niche these days, although I find megaparsec kind of awkward and I can never remember how to use it.

forge

I wrote forge as my answer to modernizing formlets,1 after the world forgot about multi-page web apps and switched to frontend/backend stratification.

However, it introduces a few novel ideas:

env-args

A simple tool called env-args that would convert environment variables to program arguments. With this, it became trivial to either pass –foo arguments or PROGRAM_FOO variables. Used for a client.

dynamic

Partly as a joke, partly serious, I made a package called dynamic which gives you dynamic types in Haskell. It makes it trivial to explore unknown data in Haskell. I’ve never used it, but in principal it is interesting.

webshow

I made a simple tool to generate a hierchical data structure browser for Haskell Show output (similar to present), and called it webshow. I have occasionallly resurrected this, when I need to explore really hairy Haskell data structures.

2018

lpaste

Back before GitHub’s gist took over, I wrote a service called lpaste which sat at lpaste.net, and superceded hpaste.org (Haskell paste), for pasting code samples. It was mostly IRC-driven. It actually featured some useful features, where e.g. pasting a revision would notify users on IRC in a given channel. That facilitated a lot of discussion about a given piece of code, with people able to make suggestions and improvements.

Spam became a large problem, and after I stopped using IRC I didn’t feel like continuing to run it.

odbc

For a client, I needed to interact with SQL Server, but it was clear that the libraries out there were all quite badly put together. So I took Microsoft’s own now-native Linux driver and wrote a from-scratch Haskell library to talk to it, here. This one is still maintained and used as far as I’m aware, but a few companies. I put special care and attention into stability and performance, and I think did a good job on that.

hex-server

I can’t explain some of the motivations for my projects. I wrote hex-server which was a ground-up implementation of Xorg-server in Haskell. I have no idea why. Curiosity, I guess.

sdl2-sprite

I was fiddling about with sdl2 at this time. sdl2-sprite just repeats a sprite for you (see the README gif). I think there are other tools around for this, but I found this one just did exactly what I wanted while making a sprite in InkScape.

caseof

The caseof package is just a proof of concept to test whether I could avoid lens and get what I wanted: trivially ask whether a value is of a particular constructor and if so, return a Maybe of the slots. Answer is: yes, you can. Does anyone use it? No, lens is too popular.

rocksdb-haskell-ng

rocksdb-haskell-ng was needed for some cryptocurrency client, who were inadvisedly using rocksdb, in Haskell, and the existing package was, well, neither stable or efficient. I rewrote it from scratch, with stability and performance in mind. I’m quite proud of the work I did on this, it was good work.

phase

Another case of having too much time on my hands perhaps. phase basically provides a frontend to Emacs in your browser. It’s not as native as the GTK or terminal frontends, but the latency wasn’t too bad. I’m not sure I’ll ever pick this up again. But it was surprisingly usable.

audit

I had to audit a number of projects at FP Complete. This emacs mode helped me interactively mark any selection of any file as viewed, accepted or problematic, with comments. I would still use this today if I need to audit or heavily review a project.

codeparty

When teaching Haskell to companies at FP Complete, it was handy to have everyone type out the answer to an exercise live on screen. For that I made codeparty, which was a bit like a mass screen share, but more efficient, and ensured everyone had the same editing experience. I would use this again if I needed to teach Haskell again.

duta

I wrote my own email server called duta, which was about being able to self-host email. I actually ran it for years; it was only because LetsEncrypt at the time was harder to use and required upgrades and maintenance that I gave up on it, but for a while I was reading my mail with my own Haskell-made email web and Emacs client.

prana

I was really into the idea of being able to interpret Haskell within Haskell, so I made a project called prana which would compile GHC Haskell down to STG, convert that STG to an internal format, and then interpret it. It turns out, there are quite a few “implicit” things in STG that you just have to know, figure out or ask around about. The GHC internals change far too often, so I gave up on this. But I took a good crack at it.

intero

intero was my “complete” (intero is Italian for ‘whole’) Haskell IDE in Emacs. I was given space at FP Complete to work on it as a product to solve the whole Haskell tooling issue. It was actually a brilliant project, and worked on almost everything, and rarely if ever broke. There was a lot of Emacs Lisp, and a modicum of Haskell in a GHCi fork I called intero.

Some of that Elisp still lives on in my Emacs config, but the project itself I sunsetted some years ago after I was subjected to one final GHC upgrade and could not bare to port my code over to yet another GHC API API change. I just gave up.

But on the whole it was a great project and had 1k users at least.

cron-daemon

I wanted a handy way to have a ‘service’ run and re-run easily, which I called cron-daemon. This was my first tool that I statically built with musl. I haven’t used this for a while, but I might use it in the future. It can be used in combination with stack build --file-watch --exec 'cron-daemon ..' to cause a service to restart after recompiling.

2017

xeno

After seeing that Neil Mitchell had written a fast XML parser by using C for the parsing, I was motivated to use it as a demonstration of writing fast parsers in Haskell. The resulting demonstration library, I called xeno, but left it for someone else to pick and maintain, which Marco Z took up. It was 100x faster than the other “fast” Haskell XML parser called Hexpat. It was faster than the C one at SAX parsing, and 2x slower at allocating a DOM, but this also predates the introduction of proper Word8, Word16, etc. types in GHC.

profile-query

I wrote a tool at FP Complete called profile-query to parse GHC’s profiler output (.prof) and to provide aggregated summaries of cost centres, with sorting by e.g. time or allocations.

It was a handy tool, but isn’t maintained today. I expect it would still work, though.

snappy

A brief experiment called snappy to try out Reflex-like FRP with SVG. It’s not as easy as you think to do this, and there are all sorts of gotchas. Where possible, don’t DIY FRP. It’s hard.

liquid-post

I wrote a post about Liquid Haskell for FP Complete, but this repo shows all the examples and they are quite good, I think.

tdiff

I still use this sometimes. tdiff just gives you timing between lines of output from a process. This can be really good for checking timings of other programs than your own.

vado

In an exhibition of sorts, I made a 90s-style web browser called vado (“I go” in Italian), which can show rich text documents and browse around. I think it’s pretty cool that I was able to do this in a few hundred lines of code, and it works/worked on Windows, macOS and Linux, too!

jl

I like jq a bit, but I always found myself just wishing I had a basic mini lambda calculus/Haskell. So I wrote a small statically typed mini language called jl. I used it for a while, but somehow I’ve managed to go years and years without needing to do JSON munging in scripts or anything. So this project died due to lack of use. I otherwise think the design and implementation are both good.

duet

I have no idea why I started working on this, but I wrote a small Haskell implementation called Duet, which is helpful for teaching because it has a substitution-based interpreter. It was based on Typing Haskell in Haskell, which was refactored a bit, more types added, etc. It’s quite a viable Haskell implementation. Great for teaching.

I never found other uses for it, because frankly I don’t fully understand the type-checker, because I didn’t author it from scratch. Future projects involved writing one from scratch, which I do understand. See Inflex or Hell.

2016

purify

I was doing more PureScript dev in 2016, so I made purify, which was basically stackage+stack, but for PureScript. It was popular for a while, but then the main PureScript package manager gained these capabilities and it wasn’t necessary anymore. But it was a solid project, I think.

labels

As part of proving out whether Haskell could really be useful as a data analysis language (answer: not really), I wrote labels, which is an extensible records package, along with CSV, JSON capabilities. It worked, actually, but nothing much came of it after that.

org-focus

In an effort to track all my time on projects, I wrote org-focus for Emacs. It was a bit like org-agenda, but included time spent, estimates, and stuff that a consultant might need. I don’t track my time with such fine-grain detail these days, so I stopped using it.

2015

descriptive

I noticed that optparse-applicative, formlets, yaml/json parsing, etc. were all a type of self-describing parser. Hence descriptive. I think the task of generalizing all of these under one framework is harder than I anticipated, despite the grand vision, and the project died.

stack

At FP Complete, clients wanted a tool that covered all their use-cases, which typically involved multi-package projects and wanting to avoid the cabal solver. Motivated by previous success with internal tools,2 we decided to make a proper tool and decided the name would be ‘stack’ (from stackage). I made the first commit for Stack. I worked on it for a year or two, alongside many people at FP Complete like Michael Sloan, Manny Borsboom, Dan Burton and Michael Snoyman, and I have used it ever since. Most everyone else did the bulk of the work, I only kick started the basics (reading cabal files, GHCi support, things like that).

The first version used Shake, but we discovered it was very hard to reason about what it was doing. Michael rewrote the scheduler to not need Shake, and did further work to basically make Stack a bit like Nix and lock down all packages, package sets into with SHA256 hashes. I wrote casa.stackage.org to store content-addressed blobs of package files for Stack to later retrieve.

It went on to become the build tool of choice for Haskell projects for some years. It’s only in recent years that cabal-install has caught up with feature parity and the sentiment seems to be shifting back to cabal-install. I still use stack because the ergonomics are more designed for my workflow.

path

As part of my work on stack, we deal with filepaths a lot, so I wrote the path package, with a blog post motivating it. I was pretty happy with this package, it solved a real need that initially a lot of people were sceptical of, but colleagues told me it saved their asses a few times.

That package is still maintained to my knowledge.

xinput-conduit

This package simply converts the xinput output (which yields all keys pressed in Xorg), and provides them as a Haskell source conduit. I was using it for keypress analysis back then. I still think it’s a nifty trick.

conditions

Conditions are a Common Lisp idea. Unlike exceptions which unwind the stack, they call a function which is bound in the dynamic scope, which gives the option of providing a different value for the calling code to use. There are whole workflows built around them in Lisp. You can be reading from a bunch of files in a loop, encounter a problem, fix it, and then continue running the program.

I was inspired to demonstrate that in Haskell. But it’s not as good as in Lisp, which embraces it fully.

haskell-trace

I wrote a small tool to add trace calls in one’s Haskell code. This is something that Haskell sorely lacks, and I can’t see acquiring any time soon.

2014

clockin

I wrote clockin as a command-line app to be able to clockin and clockout of any task. I used this for a while, maybe a year, before losing interest in clocking my time so accurately.

present

After looking at CLIM (Common Lisp Interface Manager), I really liked the idea of being able to present a value with multiple interpretations. That’s what present was about. I used template-haskell to inspect any type and derive a representation for it. Even ByteString had multiple views, e.g. as a list of bytes, as UTF-8 text, hex, a pointer, etc.

I kind of ran myself into the ground with this when it came to higher kinded types. I got stuck and lost interest. I would love to pick it up again some day.

ace

In the afterglow of growing bored of Lojban, but still enamoured by formal human languages, I got into Attempto (Latin for ‘I dare’) Controlled English. I ended up writing a parser package for it in Haskell here. It’s surprisingly comprehensive, I wrote a blog post on it. It even permits passing a record of parsers, permitting the user to define their own vocabulary and syntax for terms.

When I wrote it, use of such things was questionable. Combine it with a logic database and poof, magic understanding! In reality, not quite. Arguably, the use for such a thing in today’s brave new world of LLMs is even more questionable.

But I suppose there still lies a small place in my heart for a formal language that is also readable by anyone who speaks English.

hl

The Haskell web site has already been a bit crap. Today, it’s okay. It’s been much worse. During that period of much-worseness, I wrote hl, an alternative Haskell homepage, complete with reasoning, which I launched at haskell-lang.org as an alternative competing page, due to making no progress at all for years in trying to get access to haskell.org itself. Eventually, it did become the Haskell homepage due to some diplomatic heroics. In that sense, I suppose the project was a success. There was, as expected, lots of politics surrounding it, but that’s always the case with home pages of community projects.

formatting

I thought that the HoleyMonoid package was very neat, and decided it would make a perfect type-safe printf-like package. I called it formatting, after Common Lisp’s FORMAT.

Actually, it turned out that despite the neat trick, I really doing like the position-dependent style of printf/FORMAT at all. I prefer just writing x <> " and " <> y instead, or concat [x, "and", y]. So the whole thing became an experiment in novelty, but ultimately I lost interest and passed the maintainership onto someone else.

hindent

hindent was my bold attempt to make a complete pretty printer for Haskell, so that manual code formatting would be a thing of the past. This was quite a substantial project and took a lot of work. The blog post explains the motivations, but I just wanted to type less and get autoformatting. I later went one step further and limited it to a single style (which is what gofmt famously did), which I documented here. I even chose a style that I didn’t like, but that was popular. The decision to enforce just one style made a lot of people mad.

Years later, there was a remake project called Ormolu3, which also enforced one style. There was subsequently a fork called Fourmolu, which permitted more style configuration.4

foreign-store

The foreign-store package is a simple bit of C code wrapped in a Haskell package that lets you keep a reference to a Haskell object between GHCi reloads, which I wrote for the purpose of hot reloading. It’s actually still used to this day and maintained by someone else. There are 12 direct dependencies of it on Hackage, mostly various different ways of doing code reloading.5 They’re all fancy wrappers around this.

10 years after it had been published and not been touched for just as long, someone found and fixed a segfaulting bug in the C code. Can you believe it?

shell-conduit

I’ve been wanted to write shell scripts since 2014. This attempt, shell-conduit, was to get all available names in the PATH, available as real Haskell identifiers to run. And then “scripts” would be regular Haskell programs.

I’ve since changed my mind that this is a good idea, and see above for the Hell project.

lucid

Lucid is still actively developed, and was motivated by have a uniformity of combinators, like HTML handling in Common Lisp.

It’s also a proper monad transformer, which has a small theoretical satisfaction to it.

It’s one of my projects that is using the Immutable Publishing Policy.

gmail

When Google released a new mail app, that was a smaller version of GMail, with an API, I rejoiced and made an Emacs mode for it. Google would later kill it, as they killed all things eventually. One of many lessons learned about depending on any kind of public software service.

osdkeys

A simple tool that would display keys pressed on the screen, for screencasting.

ghc-server

ghc-server was my attempt to make a language server before “language server” was a meaningful term, inspired by SWANK for Common Lisp, that powers the SLIME Emacs package. It had a good start, but I encountered a lot of lockups and issues. Also, I couldn’t make GHC stop outputting things to stdout. I found it really hard to bring the GHC API under control. Eventually, I just gave up.

ats-examples

ATS is a fascinating C-like programming language with linear types and proofs, it has linear memory management (track malloc/free’s), among other features like unpacked data, and tail recursion, and macros. It could have been Rust before Rust. But its author, Hongwei Xi, didn’t do the best job of presenting it well. I made these examples based on reading the book.

carvo

Part of a “Maker Space” place, we wanted to make some visual representation of poetry, so I made this one which “handwrites” Poe’s The Raven.

2013

z

I wrote a post called z and accompanying source which demonstrated an idea that a language could be built upon a macro system which is based on indentation rather than delimiters like ( ) or [| .. |]. I still think it’s a fun idea, because it has unlimited extent. I might return to it one day.

ini

Back before YAML took over, there wasn’t a winning configuration format. XML had lost its lustre. So I wrote ini, which parsed the simple INI format.

Since, YAML is now de-facto standard (although TOML is floating around), so I stopped using this.

pure-io

A small project called pure-io that provided a little IO monad that would run as a pure function. I used this for tryhaskell.org.

god-mode

After suffering from RSI for a while, I had decided with Emacs I’d look at my typing with statistics. After a week or so of full day typing every day, I found that I made a significant proportion of key chords in succession. I evaluated vim modes and realised that they depart from Emacs quite a bit or lacked a story for many modes. In the end I had the thought to make the Ctrl implicitly on all the time, and this turned out to be undeniably productive and practical in the form of god-mode.

I’m still using it to this day, although it has been folded into my Emacs config.

structured-haskell-mode

In similar themes to god-mode, I made a structured editor for Emacs’s haskell-mode that would essentially let one edit Haskell code like paredit. That used a Haskell parser via haskell-src-exts, and produced a set of s-expressions for Emacs to convert to a set of markers. The minor mode was called structured-haskell-mode.

haskellnews

haskellnews was a simple web app to list all the sources of blogs, posts, tweets, etc. about Haskell. I sort of lost interest in social Mead and therefore stopped running it. But for a while I enjoyed using it.

ircbrowse

I wrote ircbrowse at ircbrowse.net to be a replacement to the much older ircbrowse.com.

ircbrowse.com was a great web site for browsing chat logs of various IRC channels, it was also infamously slow as hell. So a fundamental motivator was to make something that would be instant, and I succeeded on that, much to my personal pride.

It could handle about 30 million lines of chat across a few channels for about 10 years of logs. There were something in the order of 30k lines of chat from the #haskell channel per month.

I stopped running it after I lost interest in IRC, but it was a very satisfying project and I learned a lot about PostgreSQL’s performance characteristics in the process.

snap-app

snap-app was my small library to wrap the Snap web framework (for Haskell), with an MVC structure, so that there would be Model and Controller monads, and some associated functions.

After that, Snap became irrelevant and Yesod remained the only real web framework for a while.

cabal-sign

There was an old discussion in Haskell about signed packages. So I made a demo tool called cabal-sign which, given a .tar.gz, would sign it, and then inject the signature into the .tar.gz. It was never used by anyone, but it did contribute to a discussion.

2012

sourcemap

For fay, I thought it’d be good to include sourcemaps, so I wrote this package as a more or less line-by-line translation of the reference implementation. The spec itself was very informal. It worked, though, and performed fairly well.

fay

I wrote a language called Fay, which was a Haskell without type-classes that compiled to JavaScript, and used GHC’s type system for the type-checking.

It ended up being quite popular, it garnered its own organisation, and I had a co-maintainer called Adam Bergmark, who was very nice and smart.6

I was invited to and went to a conference in Lisbon to give a talk on it.

FP Complete used it for their IDE which was a web based Haskell IDE, which is pretty much how I got the job at FP Complete in 2013. A couple years or so later, after the IDE project petered out, we stopped using it. There were better options by then (PureScript, etc.).7

scrobble

Like many people, I used Last.fm/Audioscrobbler, and would ‘scrobble’ all my music listens to the service, and get back in response recommendations. I wrote a Haskell library to do it. It’s irrelevant these days, nobody scrobbles.

bdo

This Emacs library permits one to update .js/.css files in the browser live. This predates many “modern” tools like Vite or whatever. I don’t use it these days, because all web programming exists inside of a build system. But there was a glorious period in which that wasn’t the case.

2011

numbergeddon

I wrote a fun game called Numbergeddon, on the basis that one could rote learn arithmetic by typing it. I think I got inspiration from games at the time that involved typing out words to destroy ships, in order to practice touch-typing.

pdfinfo

This utility package just launches pdfinfo and parses the output. I needed it for work at the time.

chrisdone-xmonad

I was using xmonad in 2011, hence my config of course was published on GitHub. Like your Emacs config, it’s traditional to publish your XMonad. I don’t use tiling window managers anymore. But XMonad is a good one.

flo

I wrote a small tool that would let you annotate your source code and project a flow diagram, called flo. This could still be used today with relative ease, I think. It’s language-agnostic. I never advertised it, though.

freenect

I bought a Kinect, which was Microsoft’s XBox camera/infra-red-distance viewer hardware. There were C libs, so I wrote Haskell bindings to it and called it freenect. There were some fun things I made with it.

hulk

I wrote an IRC server for use at work for us to chat on. We used it for some years after we all left, until we eventually migrated to an app called Wire (also written in Haskell).

This was my first proper experience using threading in Haskell and working on a sockets server in Haskell. I would note that architecting an IRC server in a nice way remains an unsolved problem in my head. In any language.

ji

I wrote a library called Ji, which is a simple concept to write a web app in Haskell that sends commands to a browser of what DOM changes to make and what events to listen to.

It was taken over by Heinrich Apfelmus and renamed to threepenny-gui, after which he added many FRP-based things and has likely rewritten all of it by this point.

pgsql-simple

pgsql-simple was my naive, although fairly successful, attempt to talk to the PostgreSQL protocol directly from Haskell, without any C library. It worked, and some people used it at work. But it was slow, and not featureful. And I wasn’t interested in maintaining it as a real, serious project, with serious users. Still, it was quite fun.

css

css is a miniature DSL letting one write CSS in Haskell. Similar to SASS and Tailwind. Nothing special, but I did use it on at least one app.

url-generic

This is a fully worked out package that would, given a type that’s an instance of Data, produce a parser/printer as a URL. No one ever used it, including myself. But it was a nice exercise.

hog

I wrote an IRC logger called hog, which I used for years on my personal IRC server with friends. There isn’t much special in here, but I used it.

2010

tryhaskell

tryhaskell.org

This was a big splash when I made it, it hit the top of some big subreddits and Hacker News. It was inspired by tryruby.org, which was made by _whytheluckystiff, the mysterious Rubyist who disappeared from the community. It runs you through an interactive tutorial about Haskell basics and checks your answers.

I’ve been meaning to rewrite this one day, but so far haven’t been sufficiently inspired to do so.

It’s been running for 14 years, which is quite a long time.

jquery-console

Written for Try Haskell, this is was dumb terminal/console-like experience in the browser using JQuery. It still works correctly to this day, on tablets, phones and computers. I stopped maintaining it as a separate package years and years ago, but tryhaskell still works fine.

lisk

I had enough hubris to think I would be able to write a Lisp syntax on top of Haskell, and called it Lisk.

I was happy with Haskell, but bummed out by its syntax compared to the beauty of Lisp. That hasn’t changed today in 2024.

2009

asp-mode

I wrote a lot of ASP and PHP in my early career, so I had a small Emacs mode called asp-mode. Nothing interesting in here, other than to note how seriously I was using ASP enough to warrant a mode, but obstinantly refused to use Dreamweaver or whatever was popular at the time. Now-a-days the equivalent would be Visual Studio Code.

2008

kibro

In 2008 I was working for a small sum on a hair salon’s new web site, in Haskell. And I made a very trivial web library called “Kibro” (from the Lojban “cyberspace”), which sat upon CGI and could be ran from PHP, which is how I was running it.

lojbot

Around this time I was an enthusiastic Lojban hobbyist, so I wrote an IRC bot with various capabilities.

2006

slsk/soulski

A project for the Soulseek music sharing network. Web site, which may not remain long-term: slsk.sourceforge.net. Amusingly, it still looks great. Here’s a screenshot. Another. I started writing a C library for Soulseek: soulseek-library-0.01.zip I started writing a GUI library in C for it: exgui-library-0.1.zip I started writing a CSS parser in C for it: css-library-prototype-0.01.zip

I originally had big ambitions for this, but later lost interest. It looks like I planned to rewrite it in Common Lisp, but got bored of the project before I did.

wdn

I had a project called ‘windows desktop notes’ (WDN), that I originally wrote in C. It would overlay some plain text notes on your desktop and you could click it and get an edit box and then hit Enter to save again.

Then I ported it, or tried to, to Lisp.


  1. Ezra Cooper, Samuel Lindley, Philip Wadler and Jeremy Yallop “An idiom’s guide to formlets” Technical Report, EDI-INF-RR-1263.↩︎

  2. Michael had previously built a tool called fpbuild which basically was kind of like a big lock file and was unreasonably effective at building very large Yesod-based projects.↩︎

  3. It just had a small technological advantage of being based on GHC’s parser, rather than haskell-src-exts, which is always playing catch-up.↩︎

  4. Which I consider a bit of a setback towards the dream of making style choices a thing of the past. But I think Ormolu will win eventually. Maintaining forks is hard work.↩︎

  5. componentm-devel, espial, essence-of-live-coding, essence-of-live-coding-gloss, essence-of-live-coding-pulse, ghci-websockets, halive, jsaddle-warp, monomer, nvim-hs, rapid↩︎

  6. In retrospect I mishandled a situation where Fay was being used in production and we were breaking its APIs too often, and I blocked Adam’s master push access to the repo to give me some breathing room to slow things down, but this was obviously the wrong move, and not how you should treat early collaborators. That was my first experience managing a project, so I cut my younger self some slack. However, he was very gracious about it in the moment.↩︎

  7. See a complete history here.↩︎