Quick Start

Learn core Clojure syntax and functional programming patterns to start reading and writing Clojure code. This Quick Start teaches the essential concepts you need to explore Clojure independently.

๐ŸŽฏ What You’ll Learn

By the end of this tutorial, you’ll understand:

  • Clojure’s Lisp syntax and data structures
  • Functional programming with immutable data
  • Working with sequences and collections
  • Core functions and higher-order patterns

๐Ÿ“‹ Prerequisites

  • Clojure and Leiningen installed (see Initial Setup)
  • Basic programming knowledge in any language

๐Ÿ”ค Basic Syntax

Clojure uses prefix notation (Polish notation):

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

;; Subtraction
(- 10 3)  ;; => 7

;; Multiplication
(* 2 3 4)  ;; => 24

;; Division
(/ 10 2)  ;; => 5

;; Nested expressions
(+ (* 2 3) (- 10 4))  ;; => 12

Everything in Clojure is an expression that returns a value.

๐Ÿ“ฆ Data Structures

Clojure has four core immutable data structures:

Vectors (Indexed Collections)

[1 2 3 4 5]
["alice" "bob" "charlie"]

;; Access by index
(get [1 2 3] 0)  ;; => 1
(nth [1 2 3] 1)  ;; => 2

;; Add element
(conj [1 2 3] 4)  ;; => [1 2 3 4]

;; First and rest
(first [1 2 3])  ;; => 1
(rest [1 2 3])   ;; => (2 3)

Lists (Sequential Collections)

'(1 2 3 4 5)
(list 1 2 3)

;; Add to front
(conj '(2 3) 1)  ;; => (1 2 3)

;; First and rest
(first '(1 2 3))  ;; => 1
(rest '(1 2 3))   ;; => (2 3)

Maps (Key-Value Pairs)

{:name "Alice" :age 30 :city "Jakarta"}

;; Access values
(get {:name "Alice"} :name)  ;; => "Alice"
(:name {:name "Alice"})      ;; => "Alice"

;; Add/update
(assoc {:name "Alice"} :age 30)  ;; => {:name "Alice" :age 30}

;; Remove
(dissoc {:name "Alice" :age 30} :age)  ;; => {:name "Alice"}

Sets (Unique Collections)

#{1 2 3 4 5}

;; Add element
(conj #{1 2 3} 4)  ;; => #{1 2 3 4}

;; Check membership
(contains? #{1 2 3} 2)  ;; => true
(#{1 2 3} 2)            ;; => 2

๐Ÿ”ง Defining Values and Functions

Values (Immutable)

(def x 42)
(def name "Alice")
(def numbers [1 2 3 4 5])

Functions

;; Named function
(defn greet [name]
  (str "Hello, " name "!"))

(greet "Alice")  ;; => "Hello, Alice!"

;; Multiple parameters
(defn add [a b]
  (+ a b))

(add 5 3)  ;; => 8

;; Anonymous function
(fn [x] (* x x))
((fn [x] (* x x)) 5)  ;; => 25

;; Short syntax for anonymous functions
#(* % %)
(#(* % %) 5)  ;; => 25

;; Multiple parameters in short syntax
#(+ %1 %2)
(#(+ %1 %2) 3 4)  ;; => 7

๐Ÿ”„ Conditional Logic

;; if
(if true
  "yes"
  "no")  ;; => "yes"

(if (> 5 3)
  "greater"
  "not greater")  ;; => "greater"

;; when (no else clause)
(when (> 5 3)
  (println "5 is greater")
  "done")

;; cond (multiple conditions)
(cond
  (< 5 3) "less"
  (> 5 3) "greater"
  :else "equal")  ;; => "greater"

;; case (pattern matching)
(case 2
  1 "one"
  2 "two"
  3 "three"
  "other")  ;; => "two"

๐Ÿ“‹ Working with Sequences

Clojure excels at sequence processing:

;; map - transform each element
(map inc [1 2 3 4 5])  ;; => (2 3 4 5 6)
(map #(* % %) [1 2 3 4 5])  ;; => (1 4 9 16 25)

;; filter - keep elements matching predicate
(filter even? [1 2 3 4 5 6])  ;; => (2 4 6)
(filter #(> % 3) [1 2 3 4 5])  ;; => (4 5)

;; reduce - combine elements
(reduce + [1 2 3 4 5])  ;; => 15
(reduce * [1 2 3 4 5])  ;; => 120

;; take and drop
(take 3 [1 2 3 4 5])  ;; => (1 2 3)
(drop 2 [1 2 3 4 5])  ;; => (3 4 5)

;; partition
(partition 2 [1 2 3 4 5 6])  ;; => ((1 2) (3 4) (5 6))

๐Ÿš€ Function Composition

Combine functions for powerful transformations:

;; Threading macro (->>)
(->> [1 2 3 4 5]
     (map #(* % %))
     (filter even?)
     (reduce +))  ;; => 20

;; Equivalent to:
(reduce + (filter even? (map #(* % %) [1 2 3 4 5])))

;; Threading macro (->)
(-> {:name "Alice"}
    (assoc :age 30)
    (assoc :city "Jakarta"))  ;; => {:name "Alice" :age 30 :city "Jakarta"}

๐Ÿ’ก Immutability

All data structures are immutable by default:

(def numbers [1 2 3])
(conj numbers 4)  ;; => [1 2 3 4]
numbers           ;; => [1 2 3] (unchanged)

(def person {:name "Alice" :age 30})
(assoc person :city "Jakarta")  ;; => {:name "Alice" :age 30 :city "Jakarta"}
person                          ;; => {:name "Alice" :age 30} (unchanged)

๐Ÿงช REPL-Driven Development

The REPL is central to Clojure development:

;; Start REPL
;; lein repl

;; Load namespace
(require '[clojure.string :as str])

;; Use functions
(str/upper-case "hello")  ;; => "HELLO"
(str/split "a,b,c" #",")  ;; => ["a" "b" "c"]

;; Reload changed code
(require 'my-namespace :reload)

๐Ÿ“š Common Standard Library Functions

;; Strings
(str "Hello" " " "World")  ;; => "Hello World"
(clojure.string/upper-case "hello")  ;; => "HELLO"

;; Collections
(count [1 2 3])  ;; => 3
(empty? [])      ;; => true
(reverse [1 2 3])  ;; => (3 2 1)
(sort [3 1 2])   ;; => (1 2 3)

;; Predicates
(even? 4)   ;; => true
(odd? 3)    ;; => true
(nil? nil)  ;; => true
(empty? []) ;; => true

โœ… Next Steps

You now understand Clojure’s core concepts! To deepen your knowledge:

  1. Try the examples: Run each code snippet in the REPL
  2. Explore By Example: Clojure By Example - 80 annotated examples

๐ŸŽฏ Self-Assessment

After completing this Quick Start, you should be able to:

  • Understand Clojure’s prefix notation syntax
  • Work with vectors, lists, maps, and sets
  • Define functions with defn
  • Use map, filter, and reduce for sequence processing
  • Understand immutability and its benefits
  • Use the REPL for interactive development
Last updated