Clojure Guide — What is Clojure? Modern Lisp on the JVM
In this tutorial, you will learn about Clojure Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
Clojure is a dynamic Functional Programming language that runs on the Java Virtual Machine -- combining Lisp's homoiconicity with immutable data structures, software transactional memory, and direct access to the entire Java ecosystem.
What You'll Learn
- The history and design of Clojure
- Homoiconicity (code as data)
- Immutability by default
- Concurrency primitives
- Java interop
Why It Matters
Clojure brings the power of Lisp to the JVM -- you get the flexibility of a dynamic interactive language with access to every Java library ever written. Durga Antivirus Pro uses Clojure for rule-based threat analysis where immutable data guarantees Thread Safety without locks.
Real-World Use
Companies like Walmart, Netflix, and Apple use Clojure for high-concurrency systems. The REPL workflow means you can develop live against a running system -- changing code without restarting.
flowchart LR
A["What is Clojure?"] --> B["Leiningen"]
B --> C["REPL"]
C --> D["Syntax"]
D --> E["Sequences"]
A:::current --> B
style A fill:#2563eb,stroke:#2563eb,color:#fff
style B fill:#dbeafe,stroke:#2563eb,color:#1e40af
style C fill:#dbeafe,stroke:#2563eb,color:#1e40af
style D fill:#dbeafe,stroke:#2563eb,color:#1e40af
style E fill:#f1f5f9,stroke:#94a3b8,color:#64748b
The History of Clojure
Rich Hickey created Clojure in 2007 because he wanted a functional, concurrent language on the JVM. He combined Lisp's simplicity with immutable data structures and STM.
Key milestones:
- 2007: First public release
- 2009: Clojure 1.0
- 2013: Clojure 1.5 -- core.async
- 2018: Clojure 1.10 -- spec, clojure.spec.alpha
- 2021: Clojure 1.11 -- new functions, improvements
- 2024+: Continued development by Cognitect
Homoiconicity
In Clojure, code is data -- programs are written as Clojure data structures.
;; Code as data
(def my-code '(+ 1 2 3))
(eval my-code) ;; => 6
;; Manipulate code
(defn double-args [code]
(map (fn [x] (if (number? x) (* 2 x) x)) code))
(double-args '(+ 1 2 3)) ;; => (+ 2 4 6)
(eval (double-args '(+ 1 2 3))) ;; => 12
Immutability
All Clojure data structures are immutable and persistent -- they share structure for efficiency.
(def v [1 2 3 4 5])
(conj v 6) ;; => [1 2 3 4 5 6] (v unchanged)
(def m {:name "Bob"})
(assoc m :age 25) ;; => {:name "Bob", :age 25} (m unchanged)
Concurrency Primitives
Clojure provides atoms, refs, and agents for safe state management.
;; Atom
(def counter (atom 0))
(swap! counter inc) ;; atomic update
;; Refs (coordinated)
(def a (ref 1000))
(def b (ref 500))
(dosync
(alter a - 200)
(alter b + 200))
A Quick Taste
(println "Hello, Clojure!")
(println (+ 1 2 3 4 5))
(println (map inc [1 2 3]))
Common Mistakes
1. Forgetting parentheses
println "hello" throws an error. Everything is (function arg arg).
2. Using = for assignment
(= x 5) checks equality. Use def or let for bindings.
3. Mutating without primitives
(def m {:a 1}) then (assoc m :a 2) creates a new map -- m is unchanged. Use atoms for mutable refs.
4. Deep nesting
Use threading macros (->, ->>) to linearize pipelines.
Practice Questions
1. What is homoiconicity? Code is represented as data structures of the language itself. Clojure code is written as lists that can be manipulated like any other data.
2. How do atoms differ from refs? Atoms are for uncoordinated synchronous changes. Refs are for coordinated transactional changes across multiple state points.
3. What makes Clojure's immutability efficient? Persistent data structures share structure across versions. "Modifying" a vector reuses most of the old vector, giving O(log n) operations.
Challenge: Write a simple Clojure expression that evaluates (+ 1 2 (* 3 4)) and explain the evaluation order.
FAQ
{{< faq question="Is Clojure the same as Common Lisp?" >}} No. Clojure is a modern Lisp on the JVM/CLR/JS. Common Lisp is a separate standard with CLOS, a different ecosystem, and no JVM integration. {{< /faq >}}
{{< faq question="Can I use Java libraries from Clojure?" >}} Yes, directly and without wrappers. This is Clojure's superpower -- any Java library is available immediately. {{< /faq >}}
{{< faq question="Is Clojure good for web development?" >}} Yes. Ring (HTTP abstraction), Compojure (routing), and Luminus (full framework) make web development productive. {{< /faq >}}
{{< faq question="Does Clojure have types?" >}} Clojure is dynamically typed. For optional static typing, core.typed and Spec provide Type Checking and runtime validation. {{< /faq >}}
{{< faq question="What is core.async?" >}} A library for asynchronous programming using channels and go blocks, inspired by Go's concurrency model. {{< /faq >}}
What's Next
Now that you understand what Clojure is, proceed to set up Leiningen and write your first program.
| Topic | Description | Link |
|---|---|---|
| Leiningen | Project setup and tooling | {{< ref "02-leiningen" >}} |
| REPL | Interactive development | {{< ref "03-repl" >}} |
| Java | Compare Clojure with Java | Java |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro