Work with namespaces, require and reload source files, inspect errors, interrupt bad evaluations, and understand when a running REPL needs a restart instead of another reload.
After basic evaluation, the next REPL skill is keeping the running JVM aligned with your source files. That means understanding namespaces, reloads, interrupts, and restarts.
A namespace is more than a package-like label. It is the context where vars are interned and looked up.
1(ns orders.core)
2
3(defn order-id [order]
4 (:order/id order))
From another namespace:
1(require '[orders.core :as orders])
2(orders/order-id {:order/id 1001})
| Java concept | Clojure namespace behavior |
|---|---|
| Package | Namespaces organize names |
| Import | require loads namespaces and creates aliases |
| Static method call | Function call through namespace alias |
| Classpath source root | Namespace file must be on the classpath |
require Over load-fileUse require when loading project code:
1(require '[orders.core :as orders])
Reload after changing source:
1(require '[orders.core :as orders] :reload)
Use load-file only for scratch scripts or temporary investigations. It evaluates a file path directly and can hide namespace/file mapping problems that a normal project load would reveal.
Common reload levels:
| Need | REPL action |
|---|---|
| Load a namespace once | (require '[orders.core :as orders]) |
| Reload one changed namespace | (require '[orders.core :as orders] :reload) |
| Re-evaluate current form from editor | Editor evaluate command |
| Reload a coordinated set of namespaces | Use project workflow or a reload tool |
| Add or change dependencies | Restart REPL with updated classpath |
Dependency changes usually require a restart because the JVM process started with an existing classpath.
If you start an infinite or expensive computation:
1(loop [] (recur))
interrupt it from the terminal or editor. In a terminal REPL, Ctrl-C often interrupts the current evaluation. In editor REPLs, use the editor’s interrupt command.
Interrupt behavior depends on the REPL front end. The principle is stable: stop the running evaluation before you throw away the whole process.
When something fails, inspect the phase and cause instead of scrolling past the stack trace.
1*e
If clojure.repl helpers are available:
1(pst *e)
Modern Clojure errors include phase-oriented information such as read, compile, macro expansion, or execution. This is useful for Java engineers because not every error is a runtime exception from your business logic.
| Error phase | Usual meaning |
|---|---|
| Read | Syntax could not be read |
| Compile | Symbol, namespace, or macro expansion problem |
| Execution | Code ran and threw |
| Value could not be printed cleanly |
Reload is not a religion. Restart when the process shape changed.
| Change | Reload enough? | Restart safer? |
|---|---|---|
| Function body changed | Yes | Usually no |
| Namespace alias changed | Usually | Sometimes |
| New dependency added | No | Yes |
| Java classpath changed | No | Yes |
| Global component system changed | Maybe | Often |
| Stale live state is confusing results | No | Yes |
The Java analogy is a long-running debugger session: hot changes are useful, but some structural changes need a fresh JVM.
require for project namespaces and :reload for changed source.load-file sparingly for scratch work.