Clojure Sequences
Sequences are a fundamental abstraction in Clojure that provide a uniform way to work with collections. Clojure's sequence library includes powerful tools for lazy evaluation and functional transformations.
Sequence Basics
All Clojure collections can be treated as sequences:
(seq [1 2 3])    ; => (1 2 3)
(seq #{1 2 3})   ; => (1 3 2) (order varies)
(seq {:a 1 :b 2}) ; => ([:a 1] [:b 2])
                
                
                Lazy Sequences
Clojure can create infinite sequences that evaluate only when needed:
range
(take 5 (range)) ; => (0 1 2 3 4)
                
                
                repeat
(take 3 (repeat "x")) ; => ("x" "x" "x")
                
                
                cycle
(take 5 (cycle [1 2 3])) ; => (1 2 3 1 2)
                
                
                iterate
(take 5 (iterate inc 0)) ; => (0 1 2 3 4)
                
                
                Common Sequence Functions
map
(map inc [1 2 3]) ; => (2 3 4)
(map + [1 2 3] [4 5 6]) ; => (5 7 9)
                
                
                filter
(filter even? (range 10)) ; => (0 2 4 6 8)
                
                
                remove
(remove even? (range 10)) ; => (1 3 5 7 9)
                
                
                take/drop
(take 3 (range 10)) ; => (0 1 2)
(drop 3 (range 10)) ; => (3 4 5 6 7 8 9)
                
                
                take-while/drop-while
(take-while #(< % 5) (range 10)) ; => (0 1 2 3 4)
(drop-while #(< % 5) (range 10)) ; => (5 6 7 8 9)
                
                
                Sequence Processing
concat
(concat [1 2] [3 4]) ; => (1 2 3 4)
                
                
                interleave
(interleave [:a :b :c] [1 2 3]) ; => (:a 1 :b 2 :c 3)
                
                
                interpose
(interpose "," ["a" "b" "c"]) ; => ("a" "," "b" "," "c")
                
                
                partition
(partition 2 [1 2 3 4 5 6]) ; => ((1 2) (3 4) (5 6))
(partition 2 1 [1 2 3 4]) ; => ((1 2) (2 3) (3 4))
                
                
                Reducing Sequences
reduce
(reduce + [1 2 3 4]) ; => 10
(reduce max [3 1 4 2]) ; => 4
                
                
                reductions
(reductions + [1 2 3 4]) ; => (1 3 6 10)
                
                
                into
(into [] (map inc [1 2 3])) ; => [2 3 4]
                
                
                Transducers
Efficient, composable sequence transformations:
Creating Transducers
(def xf (map inc))
(def xf2 (filter even?))
                
                
                Using Transducers
(into [] xf [1 2 3]) ; => [2 3 4]
(transduce xf + 0 [1 2 3]) ; => 9
                
                
                Composing Transducers
(def xf (comp (map inc) (filter even?)))
(into [] xf [1 2 3 4]) ; => [2 4]
                
                
                Lazy Sequence Patterns
Generating Infinite Sequences
(def fib-seq
  (map first 
       (iterate (fn [[a b]] [b (+ a b)]) 
       [0 1]))
(take 10 fib-seq) ; => (0 1 1 2 3 5 8 13 21 34)
                
                
                Chunking
; Clojure evaluates sequences in chunks of 32 for efficiency
(take 1 (map #(do (println %) %) (range 100)))
; Prints 0-31 due to chunking
                
                
                Performance Considerations
- Prefer 
intoover repeatedconjfor building collections - Use transducers for efficient pipeline processing
 - Be mindful of chunking behavior with side effects
 - Consider 
doseqfor side-effecting operations 
Next Steps
Continue learning with:
- Clojure Macros - Extending the language with macros
 - Concurrency - Working with state safely
 - Java Interop - Using Java libraries from Clojure