Getting Started With Clojure and Visual Studio Code

Introduction

Clojure is a dynamic, functional programming language that is a joy to write. I’ve been writing it professionally for the last six months and wanted to share something I wish existed when I first got started.

To be clear this guide is not a primer on Clojure itself. I will not be going over the basics of the language, etc. There are plenty of great guides out there that are a web search away.

This guide, therefore, is primarily aimed at:

  • Programmers coming from a different language who have decided to try Clojure;
  • Programmers that are writing Clojure for the first time professionally who primarily want a quick way to get a reliable environment up and running, freeing up more time to focus on learning the language itself.

Hopefully after reading this post, you can quickly start to form a workflow for tinkering away at Clojure code in very little time.

I will assume that you are using a relatively up to date version of macOS and understand how to use Homebrew to keep the scope of this guide relatively focused.

While Homebrew also works on Linux, I’ve not personally used it, so cannot vouch if the commands have parity.

Dependencies

You will need Java, Clojure, Leiningen, and Visual Studio Code installed.

Here are some commands to run for Homebrew:

brew install adoptopenjdk clojure leiningen
brew cask install visual-studio-code

Calva

The only Visual Studio Code extension you will need to be productive with Clojure applications is Calva so make sure to have it installed.

Visual Studio Code’s User Interface

I will be using some terminology that is specific to Visual Studio Code and its UI elements.

To reduce confusion, please make sure to read this document to familiarise yourself with elements of the User Interface.

Let’s tinker

In this next part, we’re going to:

  • Create a new Clojure project using Leiningen.
  • Connect to the REPL using Visual Studio Code and Calva.
  • Evaluate Clojure expressions directly in your editor.
  • Evaluate and run tests directly in your editor.

Create a new Clojure project

Inside the directory you want to create your Clojure project, run

lein new clojure-sandbox

Open the newly created clojure-sandbox directory inside Visual Studio Code.

Jacking-In

A large part of building software with Clojure is the REPL. Most programmers are probably familiar with the concept of a REPL from other programming languages (irb for Ruby, python3 for Python, etc.).

In Clojure things are taken one step further. A REPL instance created with Leiningen has a network port that allows incoming connections.

Since this port is opened over a socket, anything with access to that port can connect to it.

The simplest way to open up a REPL instance is to run the command lein run in the clojure-sandbox directory.

We can take things a step further, however, by opening up and connecting to a REPL instance from Visual Studio Code using Calva.

Calva takes care of all of this for us by providing a command called Jack In.

In Visual Studio Code

  1. Open src/clojure_sandbox/core.clj
  2. Bring up Visual Studio Code’s command palette.
  3. Type in Jack-In and select the option Calva: Start a Project REPL and Connect (aka Jack-In)
  4. Select the Leiningen project type

You should be connected to a REPL instance and ready to evaluate some code.

Evaluating Clojure Forms

By default, Calva opens a REPL window on the right hand side after Jack-In which I will refer to as the Calva REPL going forward.

You can start to evaluate Clojure forms in the Calva REPL just like any other REPL. Type in an expression, press the return key and observe the feedback – e.g. typing (+ 2 2) followed by the return key will return 4.

Since you have jacked into a REPL connection, you can tinker around with Clojure code in your editor and evaluate the code you write. This workflow is known in the Clojure community as REPL driven development and is a powerful paradigm.

Type (+ 2 2) anywhere in core.clj and then, with your cursor anywhere on that line, you can evaluate the result of this form by pressing Ctrl + Command + C and E or selecting Calva: Evaluate Current Form in Visual Studio Code’s command palette. This will output 4 to the output window.

Calva: Evaluate Current Form in REPL Window in Visual Studio Code’s command palette will evaluate output the evaluation to the REPL window instead of the output window.

I prefer using the output window, especially on my laptop as I can close the REPL window and just use the output window for my feedback loop, saving me precious screen real-estate.

The choice of outputting to the output window or REPL is a standard evaluation pattern in Calva. There are other options to output which you should play around with.

Going forward I will focus on outputting the result to the output window, as that is my personal preference (but feel free to use the output type you prefer).

Once you start to write slightly more complex Clojure, then evaluating the result of a form might not do what you expect (e.g.)

(let [name "Muyiwa"]
  (str "Hello " name))

If your cursor is on "Hello " and try to evaluate, you will get a syntax error because we are trying to evaluate and incomplete form. If your cursor is on name then it will evaluate to a function symbol.

Essentially, for use-cases like this, you want Calva to evaluate the top-level form. If you start typing Top Level in the Visual Studio Code command palette, you can see your options. The shortcut to evaluate the top level form to the output window is Ctrl + Command + C``Space.

This is my most used command when writing Clojure in my day-to-day as the top-level form will work even for the simple examples that we tried earlier like (+ 2 2), therefore it’s worth memorising the shortcut for it.

Running Clojure Tests

To run Clojure tests in Visual Studio Code, open a test file (e.g. test/clojure_sandbox/core_test.clj and start typing calva test into the Visual Studio Code command palette.

The four options:

  • Run Tests
  • Run Current Test
  • Run Failing Tests again
  • Run Tests for Current Namespace

Should be enough for you to fit into your testing workflow. See if you can make the test pass.

Conclusion

This is really just the beginning of your journey with Clojure and REPL driven development. I highly recommend the following next steps:

I hope this has been a useful primer to help you get going and focus on playing around with Clojure.


A programming blog exploring the code, tools, and techniques behind high quality software.

© 2020 Muyiwa Olu ·