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.
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.
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.
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.
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.
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.
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.