Skip to content

Clojure

Dávid Szakállas edited this page Jul 31, 2017 · 3 revisions

Clojure

tldr; LISP on JVM

Clojure is a dynamic, general-purpose programming language, combining the approachability and interactive development of a scripting language with an efficient and robust infrastructure for multithreaded programming. Clojure is a compiled language, yet remains completely dynamic – every feature supported by Clojure is supported at runtime. Clojure provides easy access to the Java frameworks, with optional type hints and type inference, to ensure that calls to Java can avoid reflection.

Where to get help?

Community Docs: Much better than the official, has examples.

Reference: Useful, advanced documentation written by core contributors.

API Docs: Just the exported navigable API docs.

StackOverflow

Creating a project

Don't use Ant, Gradle or Maven. Use Leiningen.

Using an IDE

IntelliJ + Clojure = ❤️

There is a Clojure plugin for IntelliJ IDEA, which will give you the best experience if you like IDEs, and don't want to use Emacs. Proprietary, free for non-commercial use, acquire a license from their site: https://cursive-ide.com/

Structural editing

An absolute must have. It will auto-balance parentheses on insertion and do other nice stuff which makes it much more pleasant to write LISP code.

Setting up in Cursive

Search for Structural editing in Settings to enable it. I use the ParEdit style. Works with IdeaVIM.

Structural editing 101

Move Down/Up => exchange form under caret with next/previous form

Slurp Left/Right => extends surrounding parentheses to include next form to the left/right

Barf Left/Right => shrinks surrounding parentheses to exclude leftmost/rightmost form

Raise => Surrounding parentheses is replaced with form under caret

Kill Sexp => Removes form under caret

Kill => Removes everything to the right of caret in the surrounding parentheses

Split => Splits surrounding parentheses into two at caret

Join => Joins preceding parentheses with parentheses under cursor

Code style

tldr; Using Cursive Reformat code action will give you a pretty good formatting. Use your brain to learn the style.

Proper version LISP code is indented differently than C style. Clear your mind, don't try to apply rules learned there.

  1. The indent depends on the opening parenthesis' position. Add 2 spaces to that if this is the second form, make it line up with the second if it's the third or later:

✅ DO

(this (is (a
            (good (way)   ; second on new line so I added 2 spaces
                  (hur-)  ; second on first line, third lined up
                  (ray)))))

❌ DON'T

(this (is (a
 (bad
 (way)
 (may)
 (day)))))
  1. Opening brace should be on the same line as the first form in it. Closing brace should be on the same line as the last form in it.

✅ DO

((((good)
    (good)
    (good))))

❌ DON'T

(
  (
    (
      (bad))))

((((bad)
    )
  )
)

Using nREPL

You need to use the REPL. Super fast, and you get immideate feedback.

Cursive IDE

You should create a REPL for your project then Run REPL for MyProject. You'll have a lot of convenience actions. My favourite are:

  • Send form under caret to REPL
  • Send top form to REPL
  • Load file in REPL
  • Run tests in namespace in REPL
  • Run test under caret in REPL
  • Re-run last test action in REPL

Note: when you send a form to the REPL, it's namespace is retained. If that namespace isn't loaded yet, you won't have anything it requires, not even clojure.core (most likely it uses in-ns) resulting in strange errors such as that defn is unbound and such. So either send the whole file first, so you get the namespace declaration, or you have an option in Settings to set the form's namespace to the current namespace in the REPL when it is sent.

Linting

Clojure is a dynamic language. Use the Eastwood lint tool to prevent some common errors and unidiomatic code.

Clone this wiki locally