Following are instructions for 1) one particular setup for beginning to work in Clojure, and 2) one particular sequence of learning materials. They may not be the best for everyone! But this is what I am currently recommending for my students, many of whom are undergraduates who have taken a few computer science courses but aren’t (yet) experienced software developers or Lisp/Clojure programmers. A somewhat more comprehensive, somewhat less opinionated (but still pretty opinionated) list of Clojure resources is available here.
Setup
If you have a Github account, there is now a way to run the system that is recommended below in your browser, with zero installation of anything on your own machine. You will almost certainly want to set up VSCode/Calva on your own system to do real work, but this will let you get started if you are having any trouble getting your setup working. To do this, opening a minimal project, click here.
Install Java if it’s not already installed.
Install Visual Studio Code (VSCode).
Launch VSCode, and within it click the extensions icon (which is made of four little squares, and is probably on the left side of the window) and install the Calva extension.
Create a project:
- Choose a project name made only of lower-case letters. In the instructions below, I’ll assume you chose the name
haha
. You should replacehaha
with the name that you actually chose. - Create an empty folder called
haha
- Create the files and folders within the project in either of two ways:
- Using your operating system to make folders and a text editor to make files:
- Create a text file in
haha
calleddeps.edn
that contains just this:{}
- Create an empty folder in
haha
calledsrc
- Create an empty folder in
haha/src
that is also calledhaha
- Create a text file in
haha/src/haha
calledcore.clj
that contains just this:(ns haha.core)
- Make sure that the text files you created don’t have
.txt
extensions added by your operating system, which might add them but then hide them if it’s really sneaky. The extension for the first one should be just.edn
, and the second one should be just.clj
- Create a text file in
- Using VSCode:
- Note: There is currently a bug that will cause some warnings if you don’t type the
{}
intodeps.edn
super fast after you made it! You can ignore the warnings, although you might have to close the and reopen the project folder after you get them to make things work properly. - Select
File
>Open
and find and open the project you made by selecting the project folder and clickingOpen
. - Use the buttons next to
haha
in the Explorer pane to create the same files and folders described above. - Note that when you create the
haha
folder within thesrc
folder, the combo will appear in the Explorer like it’s a single folder calledsrc/haha
.
- Note: There is currently a bug that will cause some warnings if you don’t type the
- Using your operating system to make folders and a text editor to make files:
However you make it, the project should end up with the following structure:
haha
├── deps.edn -- contains just {}
└── src
└── haha
└── core.clj -- contains just (ns haha.core)
A few more notes on the project creation instructions above, which you should feel free to skip:
- Various tools will make the project structure for you, so you don’t have to create all of those folders and files individually, but I wanted to provide instructions that didn’t require installing anything other than Java + VSCode + Calva.
- It’s possible for the project structure to be a little simpler, with your source code file at the top level of
src
, but that will create a “single-segment” namepace (like justcore
instead ofhaha.core
), which can cause problems when your project gets more complex. To prevent that, we create a folder for your project’s code withinsrc
, and then putcore.clj
within that. This file doesn’t have to be calledcore.clj
, by the way, but that’s a common convention. - Project names can also include underscores, but references to the corresponding namespaces within your program have to use hyphens in place of the underscores. The reasons for this stem from a clash between Clojure style guidelines and Java class name rules. This can be pretty confusing, so when you’re just starting out it’s best just to stick with characters. The “all lowercase” part stems from Clojure style guidelines.
Once you have created your project, open it in VSCode if you haven’t already done so: Select File
> Open
and find and open the project you made by selecting the project folder and clicking Open
.
To start a REPL, select View
> Command Palette
and then begin typing and select Calva: Start project REPL and connect
. Alternatively, click “REPL
” in the status bar at the bottom of the window. When asked, select
deps.edn
for the project type.
Once the REPL starts up, which may take a few seconds, you’ll see a clj꞉user꞉>
prompt in the REPL pane, which will be called output.calva-repl
. You can type an expression after the prompt and hit return
(or enter
) to evaluate it and see its result.
In the Explorer pane on the left, find and open your src/haha/core.clj
file, which will open in an editor pane. You can type expressions in the editor pane that you want to both evaluate (see below) and and also save for later. Especially for larger expressions, including function definitions, it’s usually better to type them in an editor pane and evaluate them there then to work directly at the REPL prompt.
Before you evaluate any other expressions in the editor pane, you’ll have to evaluate the ns
expression at the top of the file, (ns haha.core)
(substituting your project name for haha
, of course). Alternatively, if you want to evaluate the ns
expression and everything else in the file, use the Calva: Load/Evaluate Current File and its Requires/Dependencies
command. This may show up in the command palette when the REPL is running.
To evaluate any top-level expression in the editor pane: With the cursor in or just after the expression, hold down the option
(or Alt
) key and hit return
(or enter
). Results will appear inline in the editor (but they’re not really in the file!) and also in the REPL pane. Clear the inline results from the editor pane by hitting the esc
key.
Do that first for the ns
expression, and then you can do it for anything else in that pane. This lets you write code in the editor and evaluate it there as you write it. It’s like working at the REPL prompt, except that all of your code is saved in the file that you’re editing.
You may want to get out of the “strict” editing mode (which prevents you from deleting some brackets, among other things) by clicking on the lambda near the bottom right corner of the window until it is surrounded by ()
rather than []
. Some people love strict editing mode, and there is a lot of support for it in Calva. I don’t like it myself, and always turn it off.
Fix the indentation in an expression by clicking in it and hitting the tab
key. This only works if all of the brackets in the expression match, so if you’re not in strict mode then you might have to add or delete some brackets to do this. Calva uses color and highlighting to help you match brackets. It’s a good idea to re-indent frequently, and also to avoid putting too much code on a single line. When you do this, the shape of the code will make your expression’s structure obvious.
Interrupt long-running computations with the Calva: Interrupt Running Evaluations
command, which you can call from the Command Palette. This stops the ongoing computation but leaves the REPL running so you can keep working. If you’ve messed up your environment and want to start over, you can kill the REPL by evaluating (System/exit 0)
and then restart it. Alternatively, you can click “REPL
” in the status bar at the bottom of the window and select
Disconnect from the REPL
. If you’ve changed something in a file other than the one in which you are evaluating expressions, and you want your calls to use the changed code, then you can call require
with the :reload
option, as in (require '[proj.exp :as exp] :reload)
.
Type calva
in the command palette (in the View menu) to see all Calva commands. There’s a lot more than you will probably ever want to use, but you might find it interesting. You may also want to try Calva’s “Getting Started REPL,” which will walk you through several of Calva’s features. To try it, use the command Calva: Fire up the Getting Started REPL
.
Later you may want to install the CLI tools, and run your program from your operating system command line. One way to do this is to define a function that takes a single argument, which will be called with a map of key/value pairs from the command line. For example, we could include this in our core.clj
file:
(defn joke [args]
(println "Called with:" args))
If we do that, then this command at the operating system command line:
clj -X haha.core/joke :funny 1000 :style "knock-knock"
would print:
Called with: {:funny 1000, :style knock-knock}
Learning Materials
Start by watching Clojure in a nutshell by James Trunk, but don’t worry that it mostly uses a different setup than recommended here.
Then read chapters 1 and 3 (and later probably more) of Clojure for the Brave and True by Daniel Higginbotham. No Starch Press, 2015. ISBN-10: 1593275919, ISBN-13: 978-1593275914. Available free online. Skip chapter 2 since it’s all about a setup (using emacs) that I’m not recommending here. Try out the code that the book covers as you read it, and experiment with variations.
Try and experiment with the following exercises (in any order):
- 4Clojure, interactive Clojure problems, gamified
- Clojinc, a saved REPL session intended to support semi-independent learning of Clojure
- Clojestions, suggested exercises for learning Clojure
You may also want to check out the introduction to Clojure that’s embedded in Calva’s Getting Started REPL (described above).
At some point, check out the Clojure Style Guide.
You’ll probably find the Clojure cheatsheet to be helpful too, along with ClojureDocs.