Clojure: Synchronous server sent events with virtual threads and channels
I have been playing around with turbo and datastar both of which use server sent events to broadcast updates to the client. Traditionally, server sent events work best with asynchronous ring handlers. But, personally I much prefer the simplicity of synchronous handlers, and with the advent of virtual threads we can have our cake and eat it. This post will go over how to build a synchronous ring handler for server sent events.
How to max throughput when pulling data from a third party service
Say you have an app. When a user signs up to your app you need to pull large amount of data from a third party service. The faster you can do this, the more responsive your app can be, the less your user has to wait, the better the user experience. In this post I'll break down the key things to think about when approaching this problem.
Clojure: virtual thread and dynamic var performance
In this post we'll explore some useful tools for making working with virtual threads easier. Structured concurrency helps eliminate common problems like thread leaks and cancellation delays. Scoped values let you extend parent thread based context to child threads so you can treat a group of threads as a single unit of work with the same shared context.
Clojure: managing throughput with virtual threads
Before the introduction of Java 21 virtual threads we were heavy users of claypoole a fantastic library for simple but effective parallelism using thread pools. However, things get complicated with virtual threads, they shouldn't be pooled, as they aren't a scarce resource. So how do we limit throughput when we have "unlimited" threads? In this post we will look at using java Semaphore class to implement basic token bucket rate limiting to control throughput.
A problem that comes up when web crawling is you get a lot of data that you don't necessarily care about: layout divs, scripts, classes, ids etc. Thankfully, Clojure comes with tools that make removing the data you don't care about straight forward.
Emacs: streaming radio with emms
One of the few things I miss about commuting by car is the radio. Unfortunately, I don't have a radio at home. But I do have Emacs. Surely Emacs can do radio?
Clojure: the REPL makes contributing to open source easy
Clojure has a great interactive development experience. This makes it surprisingly easy to contribute to open source. It goes something like this: you're using an open source library, you run into a potential bug, you clone the library, you write some code, you evaluate it and you see if the bug is fixed (all without ever having to restart your REPL).
Clojure: clj-kondo datalog linting
clj-kondo has had really nice datalog syntax checking for a while. However, on some projects you might have wrapped the underlying datalog query function q or be using a datalog implementation clj-kondo doesn't know about. Thankfully, it's trivial to add linting support to any implementation of the query function q as long as it conforms to the Datalog dialect of Datomic.
Clojure: virtual threads with ring and jetty
Java 19 introduce virtual threads as a preview feature. Virtual threads are lightweight threads that allow you to write server applications in a simple thread-per-request style (as opposed to async style) and still scale with near-optimal hardware utilisation. The thread-per-request approach is generally easier to reason about, maintain and debug than it's asynchronous counterparts. In this post we'll cover configuring Jetty to make your ring handlers use virtual threads and benchmark it against regular threads to show how it alleviates the need for tuning thread pools.
Clojure: virtual threads with ring and http-kit
Java 19 introduce virtual threads as a preview feature. Virtual threads are lightweight threads that allow you to write server applications in a simple thread-per-request style (as opposed to async style) and still scale with near-optimal hardware utilisation. The thread-per-request approach is generally easier to reason about, maintain and debug than it's asynchronous counterparts. In this post we'll cover configuring http-kit to make your ring handlers use virtual threads and benchmark it against regular threads to show how it alleviates the need for tuning thread pools.
Fennel: making PICO-8 games
I recently wrote a game jam game for PICO-8 using Fennel. This post goes over setting up a project to write PICO-8 games in Fennel.
Clojure: SQLite application defined SQL functions with JDBC
SQLite provides a convenient interface called Application-Defined SQL Functions that lets you create custom SQL functions that call back into your application code to compute their results. This lets us extend SQLite in Clojure. Want to query with regex or jsonpath? Want custom aggregation functions? Don't want to write C? Don't want to manage different precompiled binaries for different operating systems. No problem Application Defined SQL Functions have you covered.
SQLite: building from source on macOS
I've been playing around with Project Panama to explore building a simpler and lighter SQLite driver to use from Clojure. This required downloading and compiling SQlite from source for macOS/OS X.
Clojure: sending emails with postal and Gmail SMTP
While services like SendGrid are easy to use and offer a plethora of features like bounce and open rate monitoring, they are not the cheapest option. Gmail's SMTP service on the other hand, although not as feature rich, is more affordable. In this post we will cover setting up Gmail SMTP with postal.
Clojure: pretty print strings
clojure.pprint/pprint can be used to print Clojure data structures in a pleasing, easy-to-understand format. However, sometimes you are not printing directly to *out*, for example when using third party logging libraries/services. Thankfully, we can also use clojure.pprint/pprint generate a pretty string by wrapping it in with-out-str.
Clojure: extend honeysql to support postgres 'alter column' and 'add constraint'
Honeysql is an amazing library that lets you write SQL using clojure data structures. This makes SQL much more composable as you no longer need to smash strings together. That being said, when using it with postgresql there are some features that don't work out of the box. Thankfully, honeysql is very easy to extend. This post will show you how to add support for alter column and add constraint.
Clojure: removing namespace from keywords in response middleware
Namespaced keywords let you add a namespace to a keyword :id -> :user/id, this is a really nice feature that prevents collisions when merging two maps. For example merging {:account/id "foo"} with {:user/id "bar"}) would give you {:account/id "foo" :user/id "bar"}. This lets you avoid unnecessary data nesting and keep your data flat. However, by the time this data gets to the edge of your system, where it meets something that expects json, you will often want to remove these namespaces. This post shows you how to write a middleware that automates the removal of namespaces from keywords.
Clojure: making missing environment variables fail at compile time
Have you ever deployed something to production only to have it break because of a missing environment variable? You can eliminate this risk with a simple macro.
Heroku: buildpack for Clojure tools
Over the past 4 years I've had the fortune of working full time in Clojure. The backend for the Relish mobile app is built in Clojure. It runs on Heroku and we use lein as our build tool. This has been a great development experience. But, for the next Clojure project I wanted to try tools.deps and tools.build. Unfortunately, there isn't an official Heroku buildpack and none of the unofficial alternatives were quite what I was looking for. In the end I decided to roll my own to get comfortable with Heroku's build pack API.
Clojure: compiling java source with tools.build
Recently I stumbled over an old Java project from 2011. I wanted to see if I could get it to run. However, the original program had a bunch of IDE related build files that I no longer understood. What if I used Clojure to build the project? The fruit of that journey is covered in this blog post.
Clojure: check if instant happened today at timezone
Say you are making a digital advent calendar app. You want users to get a special reward on the days that they open your app. But only once per day and only on the days they open the app. This sounds straight forward. What about time zones? What about users who open the app on the 1st of December at 23:55 and then on the 2nd of December at 00:03? Time is tricky.
Emacs: the joy of reducing workflow friction with elisp
Emacs is an interactive, self-documenting and extensible elisp interpreter. This makes it surprisingly enjoyable to extend. It goes something like this: you notice some friction when using a command, you use Emacs' self-documenting features to learn about the command, you investigate the source, you write some elisp, you evaluate it and you try the new and improved command out (all without ever having to restart Emacs).
Emacs: building from source on macOS
I've always wanted to build Emacs from source as it lets you try new features. Native compilation in particular was something I wanted to explore. Native compilation leverages libgccjit to compile Emacs lisp code to native code making Emacs very snappy.
Clojure: code highlights for this website
When I changed the styling of this website I removed code highlights as part of an exercise in minimalism. Anyway, I recently read this awesome article about writing a Clojure highlighter from scratch in 160 lines which inspired me to add some very basic highlights back to this site. This post is about implementing my own Clojure highlighter from scratch in 8 lines (and a fraction of the functionality).
Clojure: website link checker
Writing a simple website link checker in Clojure for fun and profit. Clojure has this nifty function called re-seq that returns a lazy sequence of successive matches of a pattern in a string we can combine this with recursion to write a primitive website link checker.
Clojure: map-occurrence
Sometimes you want behaviour that differs based on the number of times an item has been seen in a sequence. Clojure doesn't come with a function that does this. Before you say "What about frequencies?", frequencies gives you the total number of occurrences in a sequence of items, not the occurrence count.
Clojure: ensuring multimethods are required
Multimethods are fantastic. They give you polymorphism without objects or classes (the best part of Object Oriented without the baggage), multiple dispatch, dynamic dispatch and strong decoupling that allows you to extend code without modifying it (open closed principle), this even extends to third party code. This decoupling is so good that it's not unheard of to deploy your system without all the defmethod extensions being required! This post will teach you how to prevent this.
Clojure: destructive macros
In this post we'll cover writing a macro that supports destructuring and does something with the bindings. More specifically we will write a macro that makes building maps from arbitrary data less verbose.
Clojure: crawling Hacker News with re-seq
Clojure has this nifty function called re-seq that returns a lazy sequence of successive matches of a pattern in a string. This is really useful for turning any string into a list of data. Let's use it to crawl Hacker News!
Clojure: cond-merge revisited
In this post we created a macro called cond-merge to conditionally associate in values to a map. In this post we will revisit some of the limitations of cond-merge when it comes to nested conditionals and conditionals that return maps that can lead to overwriting data rather than merging data.
Clojure: adding dissoc-in to our cond-merge macro
In the previous post we created a macro called cond-merge to conditionally associate in values to a map. In this post we will cover adding disassociation (removal of items) to this macro.
Clojure: cond->, deep-merge, remove-nils and the shape of data
This article will cover various ways of conditionally hydrating/decorating an existing map with additional data. We'll explore different approaches and how they affect readability of the code as well as performance.
Clojure: string similarity
Sometimes you want to compare strings for similarity. To do this we can use cosine similarity to determine how similar two strings are to each other.
Clojure: adding compile time errors with macros
Clojure is a dynamic language. But, something you might not know is that unlike a lot of other dynamic languages it's not an interpreted language it's actually compiled. Even when programming at the REPL the Java Virtual Machine's (JVM) Just In Time (JIT) compiler compiles Clojure code to byte code before evaluating it. Combining this with macros which are evaluated at compile time allows us to add compile time errors to our code.
Clojure: previous, current and next
This article will cover a common pattern of iterating over a list of items whilst keeping a reference to the previous, current and next item.
Clojure: jdbc using any and all as alternatives to in
next-jdbc uses parameterised queries to prevent SQL Injections. These queries can take parameters by passing question marks (?) in the query and then by replacing each question mark index with required values. However this can make some sql operators more challenging to use programmatically. In particular in(?,?,?). In this post we cover using postgresql's any(?) and all(?) to get around this.
Emacs: setting up Apheleia to use Prettier and Zprint
Apheleia is an awesome Emacs package for formatting code quickly using external command line tools like prettier. Not only is it fast but it also does a great job at maintaining point position relative to its surroundings (which has been one of my minor frustrations with other Emacs formatters). It's also language agnostic so you can use it with any language that has a command line formatting tool. This post will cover setting up apheleia with prettier (for JavaScript) and zprint (for Clojure).
Homebrew: write your own brew formula
GraalVM is a recent development in the Java ecosystem that allows you to generate native binaries for applications that run on the Java Virtual Machine (JVM). One of the main advantages of this is that it gets around the JVMs slow startup time which is a problem for short lived programs that are run often. This has lead to a projects like zprint releasing native binaries. This is great but, it doesn't give you a nice reproducible way to install/manage/uninstall these executables. For that we want a package manager like homebrew.
Clojure: code formatting pre-commit hook with zprint
As a codebase and the team working on it grows, it helps to keep the formatting of a project consistent. This makes the code easier to read and removes the need for unnecessary formatting debates on pull requests. One way to achieve this is to add a formatting check to your continuous integration pipeline. The problem with this solution is that it can add unnecessary overhead. You push a commit, the continuous integration job fails due to incorrect formatting, you fix the formatting issue, and push a new commit. Why can't the formatter just fix the issue itself and save you the trouble? This article will cover setting up pre-commit to automatically format Clojure code with zprint to achieve a more streamlined workflow.
Clojure: java interop with bean
One of the great things with Clojure is that it has fantastic java interop. In this article we explore the bean function and how it makes working with java objects more idiomatic.
Clojure: code as data
In Clojure, the primary representation of code is the S-expression that takes the form of nested sequences (lists and vectors). The majority of Clojure's functions are designed to operate on sequences. As a result, Clojure code can be manipulated using the same functions that are used to manipulate Clojure data. In other words, there is no distinction between code and data. Code is data. This property is known as homoiconicity. This article will explore this concept.
Clojure: persistent rate limiting
Some business needs require you to limit the number of times you do something. An example of this would be sending a daily email to users. You could achieve this by making sure you run the function only once per day. However, if that function were to crash part way through how would you know which users had already been sent their daily email and which hadn't? Resolving this without sending some users multiple emails could be a large time sink. A more robust solution would be to make the email sending function idempotent; meaning the effects of the function are applied only once per user per day and any additional applications do nothing. This article will explore one approach to solving this problem in Clojure.
Clojure: permutations
I was solving an Advent of Code problem and part of the solution required generating all the permutations of a set of numbers. Permutation is the act of arranging the members of a set into different orders. I wanted to write a recursive solution rather than an imperative solution. After some searching I found a Scheme implementation. As Scheme and Clojure are both dialects of Lisp, translating one into the other wasn't too difficult.
Ruby: functional programming
In one of my previous jobs I worked as a full stack engineer on a codebase with a Ruby backend and a Javascript/React frontend. Having used Clojure a fair bit in my spare time I was keen to code in a functional style. At first glance this seems tricky in Ruby as it doesn't have first class functions.
Clojure: flattening key paths
This article will cover how to flatten the nested key paths of a map in Clojure; turning a nested map like {:a {:b {:c {:d 1} :e 2}}} into a flat map like {:a-b-c-d 1 :a-b-e 2}.
Clojure: manipulating HTML and XML with zippers
Clojure provides a powerful namespace for manipulating HTML/XML called clojure.zip. It uses the concept of functional zipper (see Functional Pearls The zipper) to make manipulating hierarchical data structures simple and efficient. This article will cover how to use zippers to manipulate HTML/XML in Clojure.
Clojure: sorting tuples
A tuple is a finite ordered sequence of elements. A common use of tuples in Clojure is for representing pairs of data that are related; for example a key and a value when mapping over a map (hashmap/dictionary). That being said, tuples can be of any length and are a common way of representing larger sets of related data in languages that don't use maps as prolifically as Clojure. This articles explores sorting tuples in Clojure.
Clojure: generating HTML and XML
HTML and XML are ubiquitous, whether it's the pages of a static site or configuration for a logger, being able to programmatically generate these files can be really powerful. This article will cover how to generate HTML and XML files in Clojure.
Clojure: using java.time with clojure.java.jdbc
Java 8 introduced java.time to replace the existing java representations of time java.util.Date, java.sql.Timestamp etc. There were many problems with this old implementation: it wasn't thread safe, it had a clunky API and no built in representation for timezones. java.time is the successor to the fantastic joda.time project which solves all these problems. So if java.time fixes everything then why this article? Well, java.sql.Timestamp still rears its ugly head at the database layer where it is still the default representation of time in the java.jdbc database drivers. In this article we will cover how to automate the conversion between java.sql.Timestamp and java.time so you never have to deal with java.sql.Timestamp again.
Clojure: connection pooling with hikari-cp
Connection pooling is a technique for improving app performance. A pool (cache) of reusable connections is maintained meaning when users connect to the database they can reuse an existing connection. When the user finishes using the connection it is placed back in the pool for other users to use. This reduces the overhead of connecting to the database by decreasing network traffic, limiting the cost of creating new connections, and reducing the load on the garbage collector. Effectively improving the responsiveness of your app for any task that requires connecting to the database.
Clojure: emoji in strings
Sometimes your problem domain requires the use of emoji. This article will cover how emoji are represented in Clojure strings.
Clojure: a debug macro for threading macros using tap>
This article will cover how to make a debug macro using tap. See this article for an introduction to Clojure 1.10's tap system.
Clojure: intro to tap> and accessing private vars
Clojure 1.10 introduced a new system called tap. From the release notes: tap is a shared, globally accessible system for distributing a series of informational or diagnostic values to a set of (presumably effectful) handler functions. It can be used as a better debug prn, or for facilities like logging etc.
Clojure: sorting a sequence based on another sequence
Sometimes web responses contain an unordered sequence of items along with a separate manifest that specifies the ordering. This article will cover how you can write a function to sort the list of items by the manifest order as well as using Clojure Spec to generate test data to verify its output.
Clojure: personalising text
Sometimes you want to make a user's experience feel more personal. An easy way to achieve this is by personalising text based content. For example in a text base adventure game you could replace placeholders in the text with information relevant to that particular player such as their name or class. This could help make your game more engaging.
Clojure: case conversion and boundaries
Inconsistent case is a problems that tends to come up at application boundaries in your software stack. For example your Clojure codebase might use kebab-case for keywords, whilst your database uses snake_case for column names and your client wants camelCase in its json responses. Often, conventions and/or technical limitations prevent you from simply having a single case throughout your entire stack.
Clojure: contains? and some
Checking for containment, whether a collection contains an item, is a common task in software development. This post covers the ways you can check for containment in Clojure.
Clojure: sorting
Sorting collections of items is something that comes up frequently in software development. This post covers the multitude of ways you can sort things in Clojure.
Lisp-1 vs Lisp-2
The Lisp family of languages is relatively new to me. I learned both Clojure and Emacs Lisp at the same time, as Emacs is a popular Clojure editor. Learning these two lisps side by side has made me wonder about the subtle differences between the two, in particular how they approach passing functions as arguments to other functions (first class functions). It turns out this boils down to Clojure being a lisp-1 and Emacs Lisp a lisp-2.
Clojure: merging maps by key (join)
We have two sequences of maps (tables) and we want to merge them on matching keys (relations).
Clojure: string interpolation
We have a URL with some placeholder values that we want to replace.
Clojure: sending emails with SendGrid
Your business needs you to generate an automated email report containing data from your app. In this example we will use the SendGrid web API to email a .csv file.
Clojure: validating phone numbers
Sometimes you need to validate phone numbers, googlei18n/libphonenumber is a Java library for doing just that (and more). Thanks to Clojure's great java interop using this library in your project is straightforward.
Clojure: juxt and separate
Juxt is one of those higher-order functions that you never knew you needed. Despite not using it that often I find it can still be surprisingly useful. Let's check out the docs.
Clojure: map-values and map-keys
This post covers some useful Clojure functions for transforming the keys and values of maps.
Desert island code: compose and pipe
You awake a castaway on a desert island. After some time you come across an ancient computation device, the programming of which might hold your salvation!
Desert island code: curry
You awake a castaway on a desert island. After some time you come across an ancient computation device, the programming of which might hold your salvation!
Desert island code: reduce map and filter
You awake a castaway on a desert island. After some time you come across an ancient computation device. The programming of which might hold your salvation!
Managing obfuscation with annotations
Obfuscation is when you deliberately make source code difficult to read. Often code is obfuscated to conceal its purpose and deter reverse engineering. Most obfuscation tools do this by replacing class, method and field names with gibberish.
Using Proguard instead of multidex
One of the downsides of using MultiDex to overcome "The 65k limit" is that build times can increase significantly. Another option is to use ProGuard. ProGuard overcomes "The 65k limit" by removing unused method references, this can make a big difference if you are using large third party libraries like Guava. If configured correctly (disabling optimization/obfuscation) ProGuard can have little to no negative impact on your build times (in the case of larger project it can even decrease build time).
Signing your app
Android requires that all apps be digitally signed with a certificate before they can be installed. To install a release version of your app on a device it will need to signed. Thankfully signing an app is relatively straightforward.
Introduction to Kotlin on Android
Java is a very verbose language. The simplest tasks often require writing a lot of boiler plate code. Arguably, a lot of this code can be generated by IDEs like IntelliJ IDEA or Android Studio. Although, this eases the burden on the writer, it doesn't ease it on the reader. As a developer, you spend a lot more of your time reading code than writing it. This is where I find the additional cognitive overhead of boiler plate code has a habit of stymying development.
Setting up Retrolambda
Java 8 introduces the much awaited lambda expression and method reference. Unfortunately, at the time of writing, Android does not support Java 8. Thankfully, there is a project called Retrolambda that allows you to backport lambda expressions and method references to Java 7. As Android uses the Gradle build system, this guide will be using the Retrolambda gradle plugin to add Retrolambda to an Android project.
Enabling multidex on Android
As the codebase of an Android app continues to grow, it will eventually hit “The 65K limit”. This limit is characterised by the following build error:
Binding Android views with Butter Knife
As Android apps get more complex activities tend to get cluttered with calls to findViewById(id). This unnecessary boilerplate takes time to write and makes code harder to read. Butter Knife to the rescue!
Advantages of an Android free zone
In Android projects I like to set up an “Android Free Zone”. This is a Java module that doesn’t have any dependencies on the Android libraries. This is where the business logic of the app lives.