Clojure survival kit

..

Trying to work with Clojure code based on habits from Javascript, Go or Java can lead to an unpleasant experience. Here are seven pieces of advice to make your first steps into Clojure less painful.

1. Never break parenthesis balance. In block oriented languages like Java, Go and Javascript, you can often open a bunch of {, ( and [s, and ask your editor to “fix your mess”. In Clojure, this leads to a complete clusterfuck. If you open a parenthesis without closing it, you can suddenly no longer evaluate expressions, because your file does not end

My practice: keep parentheses balanced at all times. Learn some editor key bindings to make this nice.

2. Evaluate one expresion at a time. Clojure has good support for making small, incremental changes and seeing what they do. And weak support for automatically inferring where you’ve made some mistake. In Haskell or Rust, you can often mash out a lot of code and ask your compiler to find your mistake. In Clojure, the compiler won’t do that. Instead, the compiler supports a different mindset: you can make very small changes, and see instantly what they do. This requires some programming discipline. You actually need to do only one small thing between each time you evaluate your code.

My practice: I work with a piece of data, transforming it one step at a time. After each step, I see whether the result is what I expect.

3. Lean on refactor/rename from your editor. It’s easier to move from working code to working code with good renaming support. I use clojure-lsp for this with Emacs, bound to SPC c r. With Visual Studio Code and Calva, refactor/rename is bound to F12. Visual Studio Code/Calva refactor/rename uses clojure-lsp under the hood.

4. Use slurp to wrap a form. In Clojure, you often want to wrap an S-Expression in another. With slurp, you can transform your code from

(first)
[1 2 3]

to

(first
 [1 2 3])

with a single action.

5. Use expand selection to quickly select forms. To avoid breaking parentheses, we need to avoid copying a form like (first [1 2. Instead, we want to copy (first [1 2 3]) Expand selection helps us do this. Put your cursor on the ( before first, and run expand selection. Then you can copy or cut the whole thing!

Expand selection is also a great thing to use in other langauges. To the best of my knowledge, the feature appeared first in Intellij IDEA. Then Magnar Sveen implemented an Emacs package: https://github.com/magnars/expand-region.el Since then, multiple editors have adopted the expand selection action.

6. Use raise expression replacing parent to unwrap a form What if we need to go back from

(first
 [1 2 3])

to

[1 2 3]

? This is where raise expression replacing parent comes in. Put your cursor on [, then raise expression replacing parent.

7. Evaluate current toplevel form. TODO describe: motivation, example, why this matters. Wrapping in do, rich comment forms. (contributions welcome)

8. Evaluate current buffer. TODO describe. (contributions welcome)

Contributions welcome: default key bindings for Calva. This guide would be better with direct references to how to run these actions with Calva: give the correct name for the command, and its default key binding. Please propose a change to this file if you want want to add some details. The source file for this document is available on Github: https://github.com/teodorlu/play.teod.eu/tree/master/clojure-survival-kit/index.org