REPL-Driven Development and Debugging
37.1 The Workflow
Start a REPL connected to your editor (Calva/CIDER/Cursive).
Write a function, evaluate it with a keystroke, and call it in a rich comment block.
Inspect results inline, refine, and re-evaluate. Keep the program running.
Move stable experiments into tests.
Reloading: (require 'myapp.core :reload), tools.namespace ((refresh)), and Integrant's (reset) for system restarts (Module 41).
(defn parse-line [line]
(let [[name age] (clojure.string/split line #",")]
{:name name :age (parse-long age)}))
(comment
(parse-line "Ana,30") ; evaluate this form in the editor
(map parse-line ["Ana,30" "Bo,25"])
(def sample (slurp "people.csv"))
)37.2 Debugging Tools
Portal / Reveal / Morse: data inspectors that receive tap> values. Flowstorm: a time-travel debugger for Clojure. CIDER debugger (#dbg reader tag) and Cursive's IntelliJ debugger support breakpoints.
(println "x =" x) ; classic
(prn x) ; readable printing
(tap> {:event :debug :data x}) ; send values to tap listeners (Portal, Reveal, Morse)
(add-tap println) ; a simple tap listener
(clojure.pprint/pprint big-map) ; pretty printing
(clojure.repl/pst) ; print the stack trace of the last exception
*e ; the last exception
(clojure.main/ex-triage (Throwable->map *e)) ; categorized error info
(require '[clojure.tools.trace :refer [trace-ns deftrace]]) ; tracing