Destructuring binds names to values inside data structures. Describe the shape, Phel binds the pieces.
Works in let, function params (defn, fn), loop.
Sequential#
Extract from vectors/lists by position with vector syntax:
(let [[a b] [1 2]]
(+ a b)) ; => 3Nested#
Patterns nest arbitrarily deep:
(let [[a [b c]] [1 [2 3]]]
(+ a b c)) ; => 6Skipping#
_ ignores a position:
(let [[a _ b] [1 2 3]]
(+ a b)) ; => 4Rest args#
& captures the remaining elements:
(let [[a b & rest] [1 2 3 4 5]]
rest) ; => [3 4 5]PHP Coming from PHP? ›
More powerful than PHP list() or array unpacking:
// PHP - limited destructuring
[$a, $b] = [1, 2];
['a' => $x, 'b' => $y] = ['a' => 1, 'b' => 2];
// Phel - full destructuring with nesting and rest
(let [[a [b c] & rest] [1 [2 3] 4 5 6]]
// a = 1, b = 2, c = 3, rest = [4 5 6]
)
Works in more places (function params, let, loop) with more patterns.
Associative#
Extract from maps by key with map syntax:
(let [{:a a :b b} {:a 1 :b 2}]
(+ a b)) ; => 3Nested associative#
Mix map and vector patterns:
(let [{:a [a b] :c c} {:a [1 2] :c 3}]
(+ a b c)) ; => 6Defaults with :or#
Defaults for missing keys:
(let [{:name name :role role :or {role "guest"}}
{:name "Alice"}]
(str name " (" role ")")) ; => "Alice (guest)"
Without :or, missing keys bind to nil.
PHP Coming from PHP? ›
Extract values by key:
// PHP - manual extraction with defaults
$data = ['name' => 'Alice'];
$name = $data['name'];
$role = $data['role'] ?? 'guest';
// Phel - destructuring with :or
(let [{:name name :role role :or {role "guest"}}
{:name "Alice"}]
// name = "Alice", role = "guest"
)
Index-based#
Destructure vectors by index using map syntax:
(let [{0 a 1 b} [1 2]]
(+ a b)) ; => 3
(let [{0 [a b] 1 c} [[1 2] 3]]
(+ a b c)) ; => 6
Useful for specific positions in a large vector.
In function parameters#
Works directly in defn and fn params:
(defn greet [{:name name :role role :or {role "member"}}]
(str "Hello " name " (" role ")"))
(greet {:name "Alice" :role "admin"}) ; => "Hello Alice (admin)"
(greet {:name "Bob"}) ; => "Hello Bob (member)"
Sequential in params:
(defn distance [[x1 y1] [x2 y2]]
(php/sqrt (+ (* (- x2 x1) (- x2 x1))
(* (- y2 y1) (- y2 y1)))))
(distance [0 0] [3 4]) ; => 5In loop#
Loop bindings:
(loop [[head & tail] [1 2 3 4 5]
acc 0]
(if (nil? head)
acc
(recur tail (+ acc head)))) ; => 15Next steps#
- Functions and recursion - destructure function arguments
- Data structures - the collections you destructure
- Cheat sheet - keep it open while coding