Lists
Lists are the fundamental data structure in Sema. They are built from cons pairs and support a rich set of operations.
Construction & Access
list
Create a new list.
(list 1 2 3) ; => (1 2 3)
(list) ; => ()
(list "a" "b") ; => ("a" "b")cons
Prepend an element to a list.
(cons 0 '(1 2 3)) ; => (0 1 2 3)
(cons 1 '()) ; => (1)car
Return the first element of a list.
(car '(1 2 3)) ; => 1cdr
Return the rest of a list (everything after the first element).
(cdr '(1 2 3)) ; => (2 3)
(cdr '(1)) ; => ()first
Alias for car. Return the first element.
(first '(1 2 3)) ; => 1rest
Alias for cdr. Return the rest of the list.
(rest '(1 2 3)) ; => (2 3)cadr, caddr, ...
Compositions of car and cdr. Available: caar, cadr, cdar, cddr, caaar, caadr, cadar, caddr, cdaar, cdadr, cddar, cdddr.
(cadr '(1 2 3)) ; => 2
(caddr '(1 2 3)) ; => 3last
Return the last element of a list.
(last '(1 2 3)) ; => 3nth
Return the element at index N (zero-based).
(nth '(10 20 30) 1) ; => 20
(nth '(10 20 30) 0) ; => 10Association Lists
assoc
Look up a key in an association list (list of pairs). Uses equal? comparison.
(define alist '(("a" 1) ("b" 2) ("c" 3)))
(assoc "b" alist) ; => ("b" 2)
(assoc "z" alist) ; => #fassq
Like assoc but uses eq? comparison (pointer/symbol equality).
(assq 'b '((a 1) (b 2))) ; => (b 2)assv
Like assoc but uses eqv? comparison (value equality for numbers).
(assv 2 '((1 "one") (2 "two"))) ; => (2 "two")Basic Operations
length
Return the number of elements in a list.
(length '(1 2 3)) ; => 3
(length '()) ; => 0append
Concatenate lists.
(append '(1 2) '(3 4)) ; => (1 2 3 4)
(append '(1) '(2) '(3)) ; => (1 2 3)reverse
Reverse a list.
(reverse '(1 2 3)) ; => (3 2 1)range
Generate a list of integers. With one argument, generates 0 to N-1. With two, generates from start to end-1.
(range 5) ; => (0 1 2 3 4)
(range 1 5) ; => (1 2 3 4)Higher-Order Functions
map
Apply a function to each element of one or more lists.
(map (fn (x) (* x x)) '(1 2 3)) ; => (1 4 9)
(map + '(1 2 3) '(10 20 30)) ; => (11 22 33)filter
Return elements that satisfy a predicate.
(filter even? '(1 2 3 4 5)) ; => (2 4)
(filter string? '(1 "a" 2)) ; => ("a")foldl
Left fold. (foldl f init list) — accumulates from left to right.
(foldl + 0 '(1 2 3 4 5)) ; => 15
(foldl cons '() '(1 2 3)) ; => (3 2 1)foldr
Right fold. (foldr f init list) — accumulates from right to left.
(foldr cons '() '(1 2 3)) ; => (1 2 3)reduce
Like foldl but uses the first element as the initial value.
(reduce + '(1 2 3 4 5)) ; => 15for-each
Apply a function to each element for side effects.
(for-each println '("a" "b" "c"))
;; prints: a, b, c (each on a new line)sort
Sort a list in ascending order.
(sort '(3 1 4 1 5)) ; => (1 1 3 4 5)sort-by
Sort a list by a key function.
(sort-by length '("bb" "a" "ccc")) ; => ("a" "bb" "ccc")
(sort-by abs '(-3 1 -2)) ; => (1 -2 -3)flat-map
Map a function over a list and flatten the results by one level.
(flat-map (fn (x) (list x (* x 10))) '(1 2 3))
; => (1 10 2 20 3 30)apply
Apply a function to a list of arguments.
(apply + '(1 2 3)) ; => 6
(apply max '(3 1 4)) ; => 4Sublists
take
Take the first N elements.
(take 3 '(1 2 3 4 5)) ; => (1 2 3)
(take 10 '(1 2)) ; => (1 2)drop
Drop the first N elements.
(drop 2 '(1 2 3 4 5)) ; => (3 4 5)flatten
Flatten nested lists into a single list.
(flatten '(1 (2 (3)) 4)) ; => (1 2 3 4)flatten-deep
Recursively flatten all nested lists.
(flatten-deep '(1 (2 (3 (4))))) ; => (1 2 3 4)zip
Combine corresponding elements from two lists into pairs.
(zip '(1 2 3) '("a" "b" "c")) ; => ((1 "a") (2 "b") (3 "c"))partition
Split a list into two lists based on a predicate. Returns a list of two lists: elements that satisfy the predicate and those that don't.
(partition even? '(1 2 3 4 5)) ; => ((2 4) (1 3 5))Searching
member
Return the tail of the list starting from the first matching element.
(member 3 '(1 2 3 4)) ; => (3 4)
(member 9 '(1 2 3)) ; => #fany
Test if any element satisfies a predicate.
(any even? '(1 3 5 6)) ; => #t
(any even? '(1 3 5)) ; => #fevery
Test if all elements satisfy a predicate.
(every even? '(2 4 6)) ; => #t
(every even? '(2 3 6)) ; => #flist/index-of
Return the index of the first occurrence of a value, or -1 if not found.
(list/index-of '(10 20 30) 20) ; => 1
(list/index-of '(10 20 30) 99) ; => -1list/unique
Remove duplicate elements, preserving order.
(list/unique '(1 2 2 3 3 3)) ; => (1 2 3)list/dedupe
Remove consecutive duplicates from a list.
(list/dedupe '(1 1 2 2 3 3 2)) ; => (1 2 3 2)Grouping
list/group-by
Group elements by a function, returning a map.
(list/group-by even? '(1 2 3 4 5)) ; => {#f (1 3 5) #t (2 4)}list/interleave
Interleave elements from two lists.
(list/interleave '(1 2 3) '(a b c)) ; => (1 a 2 b 3 c)list/chunk
Split a list into chunks of a given size.
(list/chunk 2 '(1 2 3 4 5)) ; => ((1 2) (3 4) (5))
(list/chunk 3 '(1 2 3 4 5 6)) ; => ((1 2 3) (4 5 6))frequencies
Count occurrences of each element, returning a map.
(frequencies '(a b a c b a)) ; => {a 3 b 2 c 1}interpose
Insert a separator between elements.
(interpose ", " '("a" "b" "c")) ; => ("a" ", " "b" ", " "c")Aggregation
list/sum
Sum all numbers in a list.
(list/sum '(1 2 3 4 5)) ; => 15list/min
Return the minimum value in a list.
(list/min '(3 1 4 1 5)) ; => 1list/max
Return the maximum value in a list.
(list/max '(3 1 4 1 5)) ; => 5Random
list/shuffle
Return a randomly shuffled copy of a list.
(list/shuffle '(1 2 3 4 5)) ; => (3 1 5 2 4) (varies)list/pick
Pick a random element from a list.
(list/pick '(1 2 3 4 5)) ; => 3 (varies)Construction
list/repeat
Create a list by repeating a value N times.
(list/repeat 3 0) ; => (0 0 0)
(list/repeat 4 "x") ; => ("x" "x" "x" "x")make-list
Alias for list/repeat.
(make-list 3 0) ; => (0 0 0)iota
Generate a list of numbers. (iota count), (iota count start), or (iota count start step).
(iota 5) ; => (0 1 2 3 4)
(iota 3 10) ; => (10 11 12)
(iota 4 0 2) ; => (0 2 4 6)Splitting
list/split-at
Split a list at a given index, returning two lists.
(list/split-at '(1 2 3 4 5) 3) ; => ((1 2 3) (4 5))list/take-while
Take elements from the front while a predicate holds.
(list/take-while (fn (x) (< x 4)) '(1 2 3 4 5)) ; => (1 2 3)list/drop-while
Drop elements from the front while a predicate holds.
(list/drop-while (fn (x) (< x 4)) '(1 2 3 4 5)) ; => (4 5)Filtering
list/reject
Return elements that do NOT satisfy a predicate (inverse of filter).
(list/reject even? '(1 2 3 4 5)) ; => (1 3 5)list/find
Return the first element that satisfies a predicate, or nil if none found.
(list/find even? '(1 3 4 5 6)) ; => 4
(list/find even? '(1 3 5)) ; => nillist/sole
Return the single element matching a predicate. Errors if zero or more than one match.
(list/sole (fn (x) (> x 4)) '(1 2 3 4 5)) ; => 5Set Operations
list/diff
Return elements in the first list that are not in the second list.
(list/diff '(1 2 3 4 5) '(3 4)) ; => (1 2 5)list/intersect
Return elements present in both lists.
(list/intersect '(1 2 3 4 5) '(3 4 6)) ; => (3 4)list/duplicates
Return values that appear more than once in a list.
(list/duplicates '(1 2 2 3 3 3 4)) ; => (2 3)Extraction
list/pluck
Extract a specific key from each map in a list.
(define people (list {:name "Alice" :age 30} {:name "Bob" :age 25}))
(list/pluck :name people) ; => ("Alice" "Bob")list/key-by
Transform a list of maps into a map keyed by a function result.
(list/key-by (fn (p) (get p :id)) people) ; => map keyed by :idStatistics
list/avg
Return the average of a numeric list.
(list/avg '(2 4 6)) ; => 4.0list/median
Return the statistical median.
(list/median '(3 1 2)) ; => 2.0
(list/median '(1 2 3 4)) ; => 2.5list/mode
Return the most frequent value. If tied, returns a list.
(list/mode '(1 2 2 3 3 3)) ; => 3
(list/mode '(1 1 2 2)) ; => (1 2)Windowing
list/sliding
Create a sliding window over a list. Optional step parameter.
(list/sliding '(1 2 3 4 5) 2) ; => ((1 2) (2 3) (3 4) (4 5))
(list/sliding '(1 2 3 4 5 6) 2 3) ; => ((1 2) (4 5))list/page
Paginate a list. (list/page items page per-page) — 1-indexed pages.
(list/page (range 20) 1 5) ; => (0 1 2 3 4)
(list/page (range 20) 2 5) ; => (5 6 7 8 9)list/cross-join
Cartesian product of two lists.
(list/cross-join '(1 2) '(3 4)) ; => ((1 3) (1 4) (2 3) (2 4))Padding & Joining
list/pad
Pad a list to a target length with a fill value.
(list/pad '(1 2 3) 5 0) ; => (1 2 3 0 0)list/join
Join list elements into a string. Optional final separator.
(list/join '(1 2 3) ", ") ; => "1, 2, 3"
(list/join '(1 2 3) ", " " and ") ; => "1, 2 and 3"Generation
list/times
Generate a list by calling a function N times with the index (0-based).
(list/times 5 (fn (i) (* i i))) ; => (0 1 4 9 16)Utility
tap
Apply a side-effect function to a value, then return the original value.
(tap 42 (fn (x) (println x))) ; prints 42, returns 42