Clojure quickstart instructions

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 replace haha 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 called deps.edn that contains just this: {}
      • Create an empty folder in haha called src
      • Create an empty folder in haha/src that is also called haha
      • Create a text file in haha/src/haha called core.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
    • Using VSCode:
      • Note: There is currently a bug that will cause some warnings if you don’t type the {} into deps.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 clicking Open.
      • 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 the src folder, the combo will appear in the Explorer like it’s a single folder called src/haha.

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 just core instead of haha.core), which can cause problems when your project gets more complex. To prevent that, we create a folder for your project’s code within src, and then put core.clj within that. This file doesn’t have to be called core.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, as can be the rules about what other characters you can and can’t use, so when you’re just starting out it’s best just to stick with letters. 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 :zap:” 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 :zap:” 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.

7 Likes

I’m starting teaching Clojure tomorrow in my programming languages class. @lspector , is this the guide you gave your students this semester, and if so, how did it work out?

1 Like

Yes, and it worked well as far as I can tell!

1 Like

I also provided a prebuilt minimal project that they could download from the class website, with these instructions:

To use this project, click to download the proj.zip file, unzip it (unless your operating system does that automatically), and then in Calva, select File > Open Folder... and find and choose the folder.

Edit and run code in the folder’s src/proj/core.clj file.

To rename it, rename both the main folder and the subfolder in src. You must also change proj in the ns expression at the top of core.clj to be the new name of your project instead of proj. Use only lower-case letters in the new name for your project. The real naming restrictions aren’t actually this extreme, but this rule is the simplest way to avoid distracting trouble from file names.

1 Like

Also:

If you have a github account, you can now go here to begin working in a minimal project with Calva in your browser, with no installation of anything: GitHub - PEZ/clojure-zero: A minimal Clojure project, to fill with your own code. Ready for use in the browser with full IDE (VS Code + Calva) support

Once you launch that and wait for everything to load, you can start the REPL in the way that I said in my Quickstart instructions, with “Calva: Start a Project REPL and Connect (aka Jack-in).” Alternatively, you can do this by clicking where it says “REPL” in the status bar on the bottom of the window. If it doesn’t say REPL down there, then it may not be done loading. When you start the REPL, after a little more loading time it should say that the jack-in was successful and give you a REPL prompt. Find and open src/hello/core.clj in the explorer pane on the left, and then you can evaluate expressions in the editor pane. Note that you do have to evaluate the namespace (ns) declaration first, or use a different Calva command to load the whole file first.

1 Like

I’ve remixed some of the above with the Calva documentation I gave my students last time I used it with leiningen (which I’m not using this time), to create this intro to Calva, if anyone would find it useful:

Clojure in VS Code using Calva.pdf (87.6 KB)

Thanks @lspector for putting this together!

1 Like

Tiny thing I just finally figured out that I wanted to post somewhere:

In VSCode/Calva, to stop it from autocompleting when you hit return at the end of a symbol to go to the next line:

Settings: Editor: Accept Suggestion on Enter

I usually just turn off suggestions/autocomplete entirely. I honestly have no idea how people code with those things popping up all the time.

1 Like

I’ve discovered in Swift, which is strongly typed, and has a lot of hard-to-remember class methods and properties, like

mutating func merge<S>(
    _ other: S,
    uniquingKeysWith combine: (Value, Value) throws -> Value
) rethrows where S : Sequence, S.Element == (Key, Value)

it’s vital. But in Clojure, where every three-letter combo is a token of some kind, it seems pretty redundant.

1 Like