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 languages. 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