When you find yourself looking to flex your language learning skills, functional languages often end up on your short list. After reading this past year's "State of the Clojure Community" survey results, I couldn't help but notice how few developers who run Windows are choosing to learn Clojure. For sure, it could be the shining allure of F#. But maybe it's also that many tutorials focus on Linux or MacOS and often skip over the installation of the Java development kit. In any case, this article is going to cover getting up-and-running with Clojure, specifically when using Windows and we won't be using the Windows subsystem for Linux (WSL).
In my opinion, Clojure has a lot to offer anyone working on software development regardless of the operating system we have on our primary machine. 😉
Aside from being a functional language, Clojure has some other interesting features: there is a very real stress on immutability and that makes some other things, like concurrent or parallel code, easier to reason about. The language continues to evolve and improve and the community is reasonably friendly and accessible.
This article assumes that you have little or no experience with Clojure and that you haven't really done much in the way of setup ahead of time. To that end we've chosen some tools for you.
- Visual Studio Code for editing source code
- Calva will be the VS Code plugin we use to make working with Clojure straightforward
- Clojure runs on the Java virtual machine, we'll get our JVM from AdoptOpenJDK
- There are a couple different tools for managing Clojure projects, we'll use Leiningen
All of these are quick and painless to install, even under Windows.
We're going to start at the bottom of our list and work our way up, the first thing we will install is...
Open up your preferred web browser and navigate to the AdoptOpenJDK website. Whatever they reccomend is fine, leave the radio buttons as-is and click on the "Latest Release" button to download the Java Development Kit installer. Double-click the installer to run, accept the license agreement, and install the software.
Clojure projects are typically managed by a tool, we'll be using Leiningen. It will be responsible for downloading and managing libraries that we use in our project and building our code during development and deployment.
Leiningen is distributed as a batch file that you place in your path. This is pretty common and if you have a location for storing files like this, you can skip this part. If you don't have a location, read on!
I recommend that you store your loose executables and scripts in a directory named "bin" in your home directory. We will now create that folder and then add it to your path, making these scripts available to you from wherever you happen to be on your machine.
Open up a File Explorer and then select the directory with your name from the right-hand side to view the contents of your "home" directory ("C:\Users\YOUR_NAME"). Create a new directory for your loose scripts and call it "bin" (C:\Users\YOUR_NAME\bin"), you can double-click it to view it's contents and then click on the path at the top of the window and copy it to the clipboard.
Next, right click on the icon for "This PC" and choose the "Properties" option; the details for your computer will appear. Click on the "Advanced System Settings" item in the right-hand menu, then click on the "Environment Variables" button in the lower right-hand corner. The "Environment Variables" window will appear with the entries specific to your account at the top. Highlight the entry with the value "Path" in the "Variable" column and then press the "Edit..." button. You will be present with a list of all the directories added to your path, click the "New" button to add a new entry and then paste in (or type) the path to your new "bin" directory ("C:\Users\YOUR_NAME\bin"). Press the "OK" button to make the change permanent and then again to dismiss the "Environment Variables" window and then again to close the "System Properties" window.
Installing Leiningen is straightforward: we download the script and then place it in the same directory where we keep all of our loose tools and scripts (i.e. "C:\Users\YOUR_NAME\bin" or any location on your executable path). Open your web browser and navigate to the Leiningen website and scroll down to the "Install" section, you will see the instructions and links to the two scripts (one for Linux and one for Windows). Right click on the script for Windows ("lein.bat") and choose the "Save Link As..." item to download a copy to your machine. The last step is to place the file in your "bin" directory ("C:\Users\YOUR_NAME\bin").
Now the Leiningen is available, we can tell it to download its own dependencies so that it's ready to run. Open up a Powershell window and then run the following:
PS > lein self-install
The self-install should go pretty quickly, typically the only output you'll see is...
Downloading Leiningen now...
Just to test it out, you can ask Leiningen what version it is.
PS> lein -version Leiningen 2.9.6 on Java 11.0.11 OpenJDK 64-Bit Client VM
You probably have Visual Studio Code installed and running already, but for the sake of completion we'll provide a brief overview of that here. If you're all set with Code, you can definitely skip this step.
When you visit the Visual Studio Code download page, you can click on the big blue "Windows" download box. That will get you the "User Installer" for your machine. This version will install everything in your current account profile and, in general, is much easier to keep up-to-date.
Once downloaded, you can double-click to start the installation. After you accept the license and choose the install location, you will be presented with a couple other options. All things being equal, I recommend that you check the boxes to add an "Open with Code" action to Windows Explorer files and directories.
Calva is a plugin for Visual Studio Code that works with Leiningen (and other tools) to provide an integrated development environment where you can work on your Clojure code and get real work done. Since we already have our Java development environment and Leiningen installed, this will be very easy!
Open up Visual Studio Code and then click on the "View" menu and choose the "Extensions" item. The "Extensions" panel will load in the left hand side of the editor window and a list of popular extensions will be displayed. Click in the search box at the top of the panel and type in "Clojure". You will see that there are a variety of plugins for Code that support Clojure, "Calva" should be listed towards the top. Go ahead and click on "Calva" to select it, information about the plugin should appear in the main body of the editor window. Click on the "Install" button at the bottom of the Calva header panel to install it.
Now that we have all of the tools installed, we are ready to create our project! Close the editor panel for Calva and then click on the "View" menu and choose the "Explorer" option. Next, click on the "File" menu and choose "Open Folder..." A new open dialog will appear, navigate to where you would like to store your code and then click the "New Folder" button towards the top of the window to create a new folder, call it something like "tutorial". Next, click on the new folder to select it and click on the "Select Folder" button at the bottom of the window.
Every project needs a project file where we can store information about our project, like it's name, version and any libraries that it depends on. Click on the "File" menu and choose "New File" to create a new file. Before we start adding content to the file, choose "Save As..." from under the "File" menu and name your file "project.clj", you want to save it right into the root of your project directory.
We'll fill this file in with our project definition. You can model on the very simple one listed below (or copy it directly).
(defproject tutorial "0.1" :dependencies [[org.clojure/clojure "1.10.3"]] :main tutorial)
Here we set the name of our project, it's version and a description. Next we add the version of Clojure we're working with as a dependency (1.10.3 is the current version at the time of this writing). On the last line we point out which file should be the entry point to the project. You can name it anything, in this case we called it "tutorial" meaning that Leiningen should look for a file called "tutorial.clj" in our source code directory.
Now we can add a file of source code. Leiningen will look for a source code in the "src" directory; in the "Explorer" panel on the left-hand side of your Code window, you will see some icons appear at the top when the mouse enters the panel or it gains focus. Click on the icon that looks like a folder to create a new directory and call it "src". Click on that new directory and then click on the icon that looks like a file to create a new file inside that "src" directory and call it "tutorial.clj". Add the text below to your "tutorial.clj" file and then save it.
(ns tutorial) (defn -main [& args] (println "Hello!"))
The "-main" function represents the entry point to our application, if we were to compile our project and run it on it's own, the "-main" function is called with any parameters we pass in on the command line.
Select the "Command Palette" item from under the "View" menu, the command window will appear at the center top of your Code window, it will have a text area at the top where you can type in text and a list of matching commands in the body of the window. Type in "jack" and you will see the that the list narrows by a lot, you will see the "Calva: Start a Project REPL and Connect (aka Jack-in)" item in that list, to the right of it will be the command shortcut to invoke the task (Control-Alt-C and then Control-Alt-J). Note the shortcut as it's easier to type then navigating the command palette and then select the "Calva: Start a Project REPL..." item.
Calva will now ask you what kind of REPL session you'd like to start. Go ahead and pick "Leiningen" (the first item) to start a new REPL with the Leingingen tool. The panel at the bottom of your window will show you details as Calva sets up and connects to your REPL and then a new editor pane will appear with the contents of your session (typically called "output.calva-repl").
Go ahead and click into the REPL pane to make it active. You'll see some introductory text from Calva and then the prompt (
clj:tutorial:>). Type the following after the prompt and press return.
This will call the main function and you should see output similar to what is pictured below.
; Jack-in done. clj꞉tutorial꞉> (-main) Hello! nil clj꞉tutorial꞉>
Congratulations! You have installed all of the tools and started a new Clojure project. 🏆
There's a good amount of documentation on the Calva website, you should definitely check it out. There is a "try first" tutorial that goes over compiling your whole file or just the form you are working on. From there you can explore the rest of the documentation to get productive in no time.
Now that we have some code that knows how to say "hi", the last thing we'll do is build one Java archive (JAR) file that contains our application. We can then distribute that archive to anyone else who would like to run our code.
First we need to compile a class with our entry point so that a regular Java runtime knows how to start it up. Open up the "src\tutorial.clj" file and add
(:gen-class) to the namespace declaration at the top, like so:
(ns tutorial (:gen-class)) (defn -main [& args] (println "Hello!"))
Next we'll ask Leiningen to compile one archive for our project. If we had included any libraries in our project, Leiningen would add those to the archive as well. Click on the "View" menu and choose the "Terminal" item, a new terminal pane will open at the bottom of your code window. Type in the following and press return to build a self contained JAR file for your project.
C:\> lein uberjar
Leiningen will display some output and build your archive. You may run it like so...
C:\> java -jar target\tutorial-0.1-standalone.jar
You should see the output with the text "Hello!" At this point you should know enough to be dangerous. Good luck! 😏