Browse Learn Clojure Foundations as a Java Developer

Lists in Clojure

Understand Clojure lists as immutable head-first sequences, code forms, and occasional data structures, while avoiding Java List assumptions about indexed access.

Clojure lists are not the default “list of things” for application data. Vectors usually fill that role. Lists matter because Clojure code itself is written as lists, and because lists are efficient at adding and reading from the front.

Java engineers should avoid mapping “Clojure list” directly to java.util.List. The name is familiar, but the performance profile and idioms are different.

What a List Is Good For

Use Why lists fit Better alternative when
Code forms Clojure code is list-shaped You are modeling domain data
Stack-like head operations first, rest, and conj at the front are natural You need indexed access
Recursive examples Head/tail decomposition is simple Input depth is large or unbounded
Macro and tooling work Lists represent unevaluated forms You are just storing ordered values

Creating Lists

Use quote when you want literal list data without evaluation:

1'(1 2 3)
2;; => (1 2 3)

Use list when values should be evaluated first:

1(def x 10)
2
3(list x (+ x 1))
4;; => (10 11)

Without quote, a list in function position is evaluated as a call:

1(+ 1 2 3)
2;; => 6

That is the key syntax fact: parentheses usually mean “evaluate this form,” not “make a list.”

Head Operations

Lists are efficient at the front:

 1(def xs '(1 2 3))
 2
 3(first xs)
 4;; => 1
 5
 6(rest xs)
 7;; => (2 3)
 8
 9(conj xs 0)
10;; => (0 1 2 3)

conj adds where the collection can accept efficiently. For lists, that is the front. For vectors, it is the end.

Indexed Access Is The Wrong Habit

You can use nth on a list, but it walks through the list:

1(nth '(10 20 30) 2)
2;; => 30

If your Java code would call list.get(i) repeatedly, a Clojure vector is usually the better collection.

Lists and Sequence Functions

Lists work with ordinary sequence functions:

1(map inc '(1 2 3))
2;; => (2 3 4)
3
4(filter odd? '(1 2 3 4))
5;; => (1 3)
6
7(reduce + '(1 2 3 4))
8;; => 10

Remember that map and filter return lazy sequences. If you need a concrete vector, say so:

1(mapv inc '(1 2 3))
2;; => [2 3 4]

Java Comparison

Java habit Clojure list reality
ArrayList as default ordered data Prefer vectors
LinkedList for queue-like work Consider persistent queues, vectors, or dedicated libraries depending on access pattern
list.get(i) Use vectors for indexed access
Mutating with add Use conj and keep the returned value
Iterator loops Use sequence functions or reduce

Practice

  1. Evaluate '(1 2 3) and (list 1 2 3) and explain the difference.
  2. Compare (conj '(1 2 3) 0) with (conj [1 2 3] 0).
  3. Rewrite a Java List.get(i) loop using a vector.
  4. Use a list to represent a quoted code form, then inspect its first and rest.

Key Takeaways

  • Lists are immutable and head-first.
  • Parentheses normally evaluate code; quote prevents evaluation and returns list data.
  • conj adds to the front of a list.
  • Lists are not the usual replacement for Java ArrayList; vectors usually are.
  • Use lists heavily when reading code-as-data and occasionally for head-first sequence work.

Quiz: Lists in Clojure

### What does quote do in `'(1 2 3)`? - [x] It prevents the list from being evaluated as a function call. - [ ] It converts the list into a vector. - [ ] It mutates the list. - [ ] It imports a Java list. > **Explanation:** Quote stops evaluation and returns the list as data. ### Where does `conj` add an item to a list? - [x] The front. - [ ] The end. - [ ] A random position. - [ ] Only at index 1. > **Explanation:** `conj` adds where the collection can do so efficiently; for lists, that is the front. ### Which collection is usually better for indexed application data? - [x] Vector. - [ ] List. - [ ] Quoted symbol. - [ ] Namespace. > **Explanation:** Vectors are designed for efficient indexed access. Lists are head-first sequences. ### Why can `(nth '(10 20 30) 2)` be a poor habit in hot code? - [x] List indexing walks through the list. - [ ] Lists cannot hold numbers. - [ ] `nth` mutates the list. - [ ] `nth` only works on Java arrays. > **Explanation:** Lists are linked structures, so indexed access is not the natural operation. ### True or False: Parentheses in Clojure usually create list data without evaluation. - [ ] True - [x] False > **Explanation:** Parentheses usually form code to evaluate. Use quote or `list` when you want list data.
Revised on Saturday, May 23, 2026