26/09/2022

Writing an interpreter for Clojure in Python

During my Bachelor’s degree I had the opportunity to work on a project of my choice for ~6 months. I ended up implementing Clojure in Python, hoping to open Clojure to Python’s data science / machine learning ecosystem. As a result I spent a long time studying Clojure(Script) and their implementations.

At the end of the project, my interpreter could run a big subset of the standard library (more than 200 functions & macros, taken verbatim from Clojure core). However, the following Clojure features were missing from my implementation:

Python is a very dynamic language, and runtime code-loading made interoperability much easier. The interpreter is able to import any libraries at runtime, and interoperability works in the same way as it does in Clojure. This way I could use libraries like Pandas and matplotlib from the comfort of the REPL. Note that it is also possible to do this from Clojure itself with libpython-clj, but may not feel as smooth.

I was able to make a REPL server for my language that could talk to Clojure IDEs (by implementing the nREPL protocol). This allowed me to benefit from first-class tooling, without having to write any editor plugins.

If you are interested, you can check out my (defunct) implementation on Github.