You can use this Emacs function to easily evaluate multiple top-level forms in Clojure using CIDER.
(defun cider-eval-n-defuns (n)
"Evaluate N top-level forms, starting with the current one."
(interactive "P")
(cider-eval-region (car (bounds-of-thing-at-point 'defun))
(save-excursion
(dotimes (i (or n 2))
(end-of-defun))
(point))))
A tighter feedback loop.
One of Light Table's unforgettable features was the Instarepl, which evaluates code as it's typed. Despite having almost no regular users in 2020, Light Table continues to be discussed today because of that feature.
Clojure was designed for repl driven development, an advantage of which is faster feedback.
REPL development is faster than test driven development. Full stop. It is. It just is. If you like test driven development because of the rapid feedback loop, REPL driven development is a faster feedback loop, because you do not have to write the test part. You can try things out. ~ Stuart Halloway
With the repl, you can easily redefine functions and invoke them without restarting your application. With CIDER, you can evaluate forms and see the results without ever typing at the repl prompt.
The next logical step is getting feedback without needing to manually evaluate code. The above function cider-eval-n-defuns
is a small step in that direction.
Take the above cider-eval-n-defuns
function and bind it to an easy shortcut like C-c C-a
. Then start up CIDER and open a scratch buffer with the following code.
(defn fizzbuzz
[n]
)
[(fizzbuzz 3)
(fizzbuzz 4)
(fizzbuzz 5)
(fizzbuzz 15)]
Ignore that the solution might be trivial to you. You may be tempted to write a quick solution then evaluate the tests one by one. Likewise, you may start by writing a partial solution and then evaluate the tests selectively as you go. You might want to immediately write these tests into a deftest
and automatically run the tests when saving the file. You may even decide wrap both forms in do
and eval that top level form to get instant feedback.
Instead, you can change the function body and evaluate both forms at once by calling cider-eval-n-defuns
with no arguments. As you change the function body, you can almost immediately see how your changes affect the result of evaluating the function.
You've re-framed your development process. Instead of determining tests upfront and driving toward passing them, you're creatively exploring new approaches and ideas until you arrive at one that you like.
I would love to see an Instarepl mode for CIDER.
Given CIDER's roadmap, it's simply not a priority right now. Some day it could be though. My hope is that this gist gives Clojure programmers a taste of how imaginative programming Clojure can be.
And it's a great tool for when you want to evaluate the buffer in its entirety. ;)