Synopsis: I talk about the value of paredit in Emacs and show a trick which allows you to insert the result of any given Clojure expression directly underneath that expression.
As I said in the first post, a good set of tools can make a big difference in productivity and enjoyment while working in any language, and Clojure is certainly no exception. The most important tool in your toolbox, regardless of language, is your editor. Editing Lisp code in particular is much more natural with the right editor setup.
I have been using Emacs since the 1990s, though I still consider myself a novice (Emacs is that way). Though good alternatives exist, over half of the Clojure community has adopted Emacs despite its lack of polish and its Himalayan learning curve. Emacs is massively customizable, with hundreds of plugins available, and can be extended to just about any degree using its own flavor of Lisp.
While I’ll give a few Emacs configuration tips below, I don’t give a complete recipe for customizing Emacs here. My Emacs configuration file is on GitHub if you are interested.
Though it takes a little getting used to, I started using paredit mode exclusively a year or so and it has made a huge difference, not only for my productivity with the language, but also in my enjoyment and appreciation of Lisp in general.
In paredit, the units of code are not lines of text or sequences of characters, but s-expressions (generally, lists). In other words, paredit gives you the ability to easily manipulate the data structures that your code is built out of. With various key combinations, you can kill expressions, split them, join them, expell (“barf”) or absorb (“slurp”) neighboring expressions, and so on. This excellent cheat sheet covers the whole range of commands and keybindings.
I think that it wasn’t until I started using paredit that I really got used to all those parentheses. Now editing non-Lisp code feels unnatural to me, since I don’t have the ability to sling blocks of code about with the same ease without those parentheses steering my editor. And, though it’s hard to give a specific reason for this, working directly with trees of Lisp expressions gives me a feeling of somehow being closer to the essence of computation.
An even more important tool is CIDER, which integrates the Clojure REPL directly with Emacs. The upshot of this kind of integration is that one can evaluate Clojure code directly from the editor with a single key combination and see the results instantly.
I bind my own key combinations to the common CIDER commands to make them as quick to execute as possible:
(add-hook 'clojure-mode-hook
'(lambda ()
(paredit-mode 1)
;; Actual keyboard bindings follow:
Start CIDER REPL with control-o-j
:
(define-key clojure-mode-map (kbd “C-o j”) 'cider-jack-in)
Restart CIDER REPL
with control-o-J
(in case of dirty JVM, etc.):
(define-key clojure-mode-map (kbd “C-o J”) 'cider-restart)
Use ⌘-i
to evaluate previous expression and display
result in minibuffer (I am on a Mac):
(define-key clojure-mode-map (kbd “s-i”) 'cider-eval-last-sexp)
Rather than showing in minibuffer, use control-o y
to insert the result directly in the code.
(define-key clojure-mode-map (kbd “C-o y”)
(lambda ()
(interactive)
(insert “\n;;=>\n”)
(cider-eval-last-sexp 't)))
As an example of using this, suppose I have the following Clojure code:
(range 100)
|
With the position of my cursor denoted by |
, and I type control-o y
, I get:
(range 100)
;;=>
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
95 96 97 98 99)
To see a video of this trick in action, check out this demonstration
video. I find that using cider-eval-last-sexp
feels a little like working with the InstaREPL in Light Table, except that here you can actually preserve and edit the results
of expressions rather than just viewing them inline. This is
especially helpful for the style of semi-literate programming I
will describe in a coming post.
Other Emacs plugins which I use and recommend are:
To install Emacs packages, e.g. paredit, M-x
install-package [RET] paredit
. Or, steal the code from my init.el file which installs and updates any missing
packages from a list of packages you define.
Conference talks and online videos are a great way to find Emacs tricks to steal. For example, I’ve seen people run unit tests from inside Emacs and display failures inline with the code, which is a very cool trick, though not exactly what I want. The best way to increase your Emacs-fu is to sit down with a grizzled Emacs guru and compare notes and techniques. I wish I had more opportunities to do this.
In the next post, we’ll talk about test-driven development and how “RDD” (REPL-driven development) and TDD enhance and complement each other.
© 2016 John Jacobsen. Created with unmark. CSS by Tufte-CSS.