Skip to content

Clojure Guide — What is Clojure? Modern Lisp on the JVM

DodaTech Updated 2026-06-28 4 min read

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