--- title: "Standard Library: Lists and Sequences" output: arl::arl_html_vignette pkgdown: as_is: true vignette: > %\VignetteIndexEntry{Standard Library: Lists and Sequences} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") arl::register_knitr_engine() ``` *Examples on this page may reference functions from other stdlib modules without showing explicit `(import ...)` statements. In the REPL or your own code, you will need to import non-prelude modules before using their exports — see [Importing modules](lang-reference.html#importing-modules).* ## List Operations {#section-list-operations} Core list constructors and accessors, following Scheme conventions. Lists in Arl are backed by R lists; [`car`](#car)/[`cdr`](#cdr) provide the fundamental decomposition and [`cons`](#cons) the fundamental construction. ### call {#call} Convert a list to a callable form. **Signature:** `(call lst)` **Parameters:** - **`lst`** — List to convert to a call object. **Examples:** ```{arl} (call (list '+ 1 2)) ; => language: (+ 1 2) ``` ```{arl, include=FALSE} (assert-true (is.call (call (list '+ 1 2)))) ``` **See also:** [eval](lang-core.html#eval), apply --- ### caar {#caar} car of car. **Signature:** `(caar x)` **Parameters:** - **`x`** — Nested list to access. --- ### cadr {#cadr} car of cdr. **Signature:** `(cadr x)` **Parameters:** - **`x`** — List to access. --- ### cdar {#cdar} cdr of car. **Signature:** `(cdar x)` **Parameters:** - **`x`** — Nested list to access. --- ### cddr {#cddr} cdr of cdr. **Signature:** `(cddr x)` **Parameters:** - **`x`** — List to access. --- ### caaar {#caaar} car of car of car. **Signature:** `(caaar x)` **Parameters:** - **`x`** — Nested list to access. --- ### caadr {#caadr} car of car of cdr. **Signature:** `(caadr x)` **Parameters:** - **`x`** — Nested list to access. --- ### cadar {#cadar} car of cdr of car. **Signature:** `(cadar x)` **Parameters:** - **`x`** — Nested list to access. --- ### caddr {#caddr} car of cdr of cdr. **Signature:** `(caddr x)` **Parameters:** - **`x`** — List to access. --- ### cdaar {#cdaar} cdr of car of car. **Signature:** `(cdaar x)` **Parameters:** - **`x`** — Nested list to access. --- ### cdadr {#cdadr} cdr of car of cdr. **Signature:** `(cdadr x)` **Parameters:** - **`x`** — Nested list to access. --- ### cddar {#cddar} cdr of cdr of car. **Signature:** `(cddar x)` **Parameters:** - **`x`** — Nested list to access. --- ### cdddr {#cdddr} cdr of cdr of cdr. **Signature:** `(cdddr x)` **Parameters:** - **`x`** — List to access. --- ### cadddr {#cadddr} car of cdr of cdr of cdr. **Signature:** `(cadddr x)` **Parameters:** - **`x`** — List to access. --- ### cddddr {#cddddr} cdr of cdr of cdr of cdr. **Signature:** `(cddddr x)` **Parameters:** - **`x`** — List to access. --- ### list* {#list-star} Build list ending with last arg. **Signature:** `(list* args...)` **Parameters:** - **`args`** — Elements to combine; the last argument is appended as a tail. **Examples:** ```{arl} (list* 1 2 (list 3 4)) ; => (1 2 3 4) (list* 1 2 3) ; => (1 2 3) (list*) ; => () ``` ```{arl, include=FALSE} (assert-equal (list 1 2 3 4) (list* 1 2 (list 3 4))) (assert-equal (list 1 2 3) (list* 1 2 3)) (assert-equal (list) (list*)) ``` **See also:** list, [cons](#cons), [append](#append) --- ### append {#append} Concatenate multiple lists into one. **Signature:** `(append lists...)` **Parameters:** - **`lists`** — Lists to concatenate in order. **Examples:** ```{arl} (append (list 1 2) (list 3 4)) ; => (1 2 3 4) (append (list 1) (list 2) (list 3)); => (1 2 3) (append (list 1 2) (list)) ; => (1 2) ``` ```{arl, include=FALSE} (assert-equal (list 1 2 3 4) (append (list 1 2) (list 3 4))) (assert-equal (list 1 2 3) (append (list 1) (list 2) (list 3))) (assert-equal (list 1 2) (append (list 1 2) (list))) ``` **See also:** [cons](#cons), [list*](#list-star) --- ### reverse {#reverse} Reverse list. **Signature:** `(reverse x)` **Parameters:** - **`x`** — List to reverse. **Examples:** ```{arl} (reverse (list 1 2 3)) ; => (3 2 1) (reverse (list)) ; => () ``` ```{arl, include=FALSE} (assert-equal (list 3 2 1) (reverse (list 1 2 3))) (assert-equal (list) (reverse (list))) ``` --- ### first {#first} Alias for car. **Signature:** `(first lst)` **Parameters:** - **`lst`** — Source list. **Examples:** ```{arl} (first (list 10 20 30)) ; => 10 ``` ```{arl, include=FALSE} (assert-equal 10 (first (list 10 20 30))) ``` **See also:** [car](#car), [rest](#rest), [last](#last) --- ### second {#second} Return second element or #nil. **Signature:** `(second lst)` **Parameters:** - **`lst`** — Source list. **Examples:** ```{arl} (second (list 10 20 30)) ; => 20 ``` ```{arl, include=FALSE} (assert-equal 20 (second (list 10 20 30))) ``` **See also:** [first](#first), [third](#third) --- ### third {#third} Return third element or #nil. **Signature:** `(third lst)` **Parameters:** - **`lst`** — Source list. **Examples:** ```{arl} (third (list 10 20 30)) ; => 30 ``` ```{arl, include=FALSE} (assert-equal 30 (third (list 10 20 30))) ``` **See also:** [second](#second), [fourth](#fourth) --- ### fourth {#fourth} Return fourth element or #nil. **Signature:** `(fourth lst)` **Parameters:** - **`lst`** — Source list. **Examples:** ```{arl} (fourth (list 1 2 3 4)) ; => 4 ``` ```{arl, include=FALSE} (assert-equal 4 (fourth (list 1 2 3 4))) ``` **See also:** [third](#third) --- ### rest {#rest} Alias for cdr. **Signature:** `(rest lst)` **Parameters:** - **`lst`** — Source list. **Examples:** ```{arl} (rest (list 1 2 3)) ; => (2 3) ``` ```{arl, include=FALSE} (assert-equal (list 2 3) (rest (list 1 2 3))) ``` **See also:** [cdr](#cdr), [first](#first) --- ### last {#last} Return last item or #nil. **Signature:** `(last lst)` **Parameters:** - **`lst`** — Source list. **Examples:** ```{arl} (last (list 1 2 3)) ; => 3 (last (list 42)) ; => 42 (last (list)) ; => #nil ``` ```{arl, include=FALSE} (assert-equal 3 (last (list 1 2 3))) (assert-equal 42 (last (list 42))) (assert-equal #nil (last (list))) ``` **See also:** [first](#first), [nth](#nth) --- ### nth {#nth} Return nth item (0-based). **Signature:** `(nth lst n)` **Parameters:** - **`lst`** — Source list. - **`n`** — 0-based index of the element to retrieve. **Examples:** ```{arl} (nth (list 'a 'b 'c) 0) ; => a (nth (list 'a 'b 'c) 2) ; => c ``` ```{arl, include=FALSE} (assert-equal 'a (nth (list 'a 'b 'c) 0)) (assert-equal 'c (nth (list 'a 'b 'c) 2)) ``` **See also:** [first](#first), [last](#last) --- ### car {#car} Return first element or #nil. **Signature:** `(car lst)` **Examples:** ```{arl} (car (list 1 2 3)) ; => 1 (car (list)) ; => #nil (car (cons 'a 'b)) ; => a ``` ```{arl, include=FALSE} (assert-equal 1 (car (list 1 2 3))) (assert-equal #nil (car (list))) ``` **See also:** [cdr](#cdr), [cons](#cons), [first](#first) --- ### cdr {#cdr} Return list without first element (or cdr of dotted pair). **Signature:** `(cdr lst)` **Examples:** ```{arl} (cdr (list 1 2 3)) ; => (2 3) (cdr (list 1)) ; => () (cdr (cons 'a 'b)) ; => b ``` ```{arl, include=FALSE} (assert-equal (list 2 3) (cdr (list 1 2 3))) (assert-equal (list) (cdr (list 1))) ``` **See also:** [car](#car), [cons](#cons), [rest](#rest) --- ### cons {#cons} Prepend item to list or call; dotted pair when cdr is not a list. **Signature:** `(cons item lst)` **Examples:** ```{arl} (cons 1 (list 2 3)) ; => (1 2 3) (cons 'a (list 'b)) ; => (a b) (cons 'a 'b) ; => dotted pair (a . b) ``` ```{arl, include=FALSE} (assert-equal (list 1 2 3) (cons 1 (list 2 3))) (assert-equal (list 'a 'b) (cons 'a (list 'b))) ``` **See also:** [car](#car), [cdr](#cdr), [append](#append) --- ## Association Lists {#section-association-lists} Association lists (alists) map keys to values. Each entry is a list whose `car` is the key and whose `cadr` is the value. `assoc` and friends search by key; `rassoc` searches by value. ### assoc {#assoc} Find first alist entry (list or dotted pair) with matching key (uses ==). **Signature:** `(assoc key alist)` **Parameters:** - **`key`** — Key to search for. - **`alist`** — Association list of (key value) entries. **Examples:** ```{arl} (assoc 'b (list (list 'a 1) (list 'b 2) (list 'c 3))) ; => (b 2) (assoc 'z (list (list 'a 1) (list 'b 2))) ; => #nil ``` ```{arl, include=FALSE} (assert-equal (list 'b 2) (assoc 'b (list (list 'a 1) (list 'b 2) (list 'c 3)))) (assert-equal #nil (assoc 'z (list (list 'a 1) (list 'b 2)))) ``` **See also:** [rassoc](#rassoc), [assoc-by-identical?](#assoc-by-identical-p), [assoc-by-==](#assoc-by-eq-eq) --- ### assoc-by-equal? {#assoc-by-equal-p} Find first alist entry with key matching under equal? (deep structural comparison). Requires `(import equality)` for `equal?`. **Parameters:** - **`key`** — Key to search for. - **`alist`** — Association list of (key value) entries. **See also:** [assoc](#assoc) --- ### assoc-by-identical? {#assoc-by-identical-p} Find first alist entry with matching key (uses R's identical?). **Signature:** `(assoc-by-identical? key alist)` **Parameters:** - **`key`** — Key to search for. - **`alist`** — Association list of (key value) entries. **See also:** [assoc](#assoc), [assoc-by-==](#assoc-by-eq-eq) --- ### assoc-by-== {#assoc-by-eq-eq} Find first alist entry with matching key (uses R's ==). **Signature:** `(assoc-by-== key alist)` **Parameters:** - **`key`** — Key to search for. - **`alist`** — Association list of (key value) entries. **See also:** [assoc](#assoc), [assoc-by-identical?](#assoc-by-identical-p) --- ### assq {#assq} assq cannot be properly implemented in R (no eq?). Use assoc (equal?), assoc-by-identical?, or assoc-by-== instead. **Signature:** `(assq key alist)` **Parameters:** - **`key`** — Key to search for (unused; raises error). - **`alist`** — Association list (unused; raises error). **Note:** assq cannot be properly implemented in R (no eq?). Use assoc, assoc-by-identical?, or assoc-by-== instead. --- ### assv {#assv} assv cannot be properly implemented in R (no eqv?). Use assoc (equal?), assoc-by-identical?, or assoc-by-== instead. **Signature:** `(assv key alist)` **Parameters:** - **`key`** — Key to search for (unused; raises error). - **`alist`** — Association list (unused; raises error). **Note:** assv cannot be properly implemented in R (no eqv?). Use assoc, assoc-by-identical?, or assoc-by-== instead. --- ### rassoc {#rassoc} Find first alist entry with matching value (searches cdr of entries; uses equal?). **Signature:** `(rassoc value alist)` **Parameters:** - **`value`** — Value to search for in the second position of each entry. - **`alist`** — Association list of (key value) entries. **Examples:** ```{arl} (rassoc 2 (list (list 'a 1) (list 'b 2) (list 'c 3))) ; => (b 2) (rassoc 9 (list (list 'a 1) (list 'b 2))) ; => #nil ``` ```{arl, include=FALSE} (assert-equal (list 'b 2) (rassoc 2 (list (list 'a 1) (list 'b 2) (list 'c 3)))) (assert-equal #nil (rassoc 9 (list (list 'a 1) (list 'b 2)))) ``` **See also:** [assoc](#assoc), [rassoc-by-equal?](#rassoc-by-equal-p) --- ### rassoc-by-equal? {#rassoc-by-equal-p} Alias for rassoc: find first alist entry with value matching under equal?. **Signature:** `(rassoc-by-equal? value alist)` **Parameters:** - **`value`** — Value to search for in the second position of each entry. - **`alist`** — Association list of (key value) entries. **See also:** [rassoc](#rassoc) --- ## List Generation {#section-list-generation} Utilities for creating lists of numbers or repeated values. ### range {#range} Generate numeric range from start to end (exclusive) with optional step. **Signature:** `(range start end step-args...)` **Parameters:** - **`start`** — Start value (inclusive). - **`end`** — End value (exclusive). - **`step-args`** — Optional step size (default 1). **Examples:** ```{arl} (range 0 5) ; => (0 1 2 3 4) (range 0 10 2) ; => (0 2 4 6 8) (range 5 0 -1) ; => (5 4 3 2 1) ``` ```{arl, include=FALSE} (assert-equal (list 0 1 2 3 4) (range 0 5)) (assert-equal (list 0 2 4 6 8) (range 0 10 2)) (assert-equal (list 5 4 3 2 1) (range 5 0 -1)) ``` **See also:** [iota](#iota), [make-list](#make-list) --- ### iota {#iota} Generate sequence of count numbers starting from start (default 0) with step (default 1). **Signature:** `(iota count args...)` **Parameters:** - **`count`** — Number of elements to generate. - **`args`** — Optional start (default 0) and step (default 1). **Examples:** ```{arl} (iota 5) ; => (0 1 2 3 4) (iota 5 1) ; => (1 2 3 4 5) (iota 5 0 2) ; => (0 2 4 6 8) ``` ```{arl, include=FALSE} (assert-equal (list 0 1 2 3 4) (iota 5)) (assert-equal (list 1 2 3 4 5) (iota 5 1)) (assert-equal (list 0 2 4 6 8) (iota 5 0 2)) ``` **See also:** [range](#range), [make-list](#make-list) --- ### make-list {#make-list} Create list of n copies of value. **Signature:** `(make-list n value)` **Parameters:** - **`n`** — Number of copies. - **`value`** — Element to repeat. **Examples:** ```{arl} (make-list 3 'x) ; => (x x x) (make-list 0 'x) ; => () ``` ```{arl, include=FALSE} (assert-equal (list 'x 'x 'x) (make-list 3 'x)) (assert-equal (list) (make-list 0 'x)) ``` **See also:** [iota](#iota), [range](#range) --- ## Additional List Accessors {#section-additional-list-accessors} ### list-ref {#list-ref} Scheme-style list accessor (alias for nth). **Signature:** `(list-ref lst index)` **Parameters:** - **`lst`** — Source list. - **`index`** — 0-based index of the element to retrieve. **Examples:** ```{arl} (list-ref (list 'a 'b 'c) 1) ; => b ``` ```{arl, include=FALSE} (assert-equal 'b (list-ref (list 'a 'b 'c) 1)) ``` **See also:** [nth](#nth) --- ### list-tail {#list-tail} Return list without first k elements. **Signature:** `(list-tail lst k)` **Parameters:** - **`lst`** — Source list. - **`k`** — Number of leading elements to skip. **Examples:** ```{arl} (list-tail (list 'a 'b 'c 'd) 2) ; => (c d) (list-tail (list 1 2 3) 0) ; => (1 2 3) ``` ```{arl, include=FALSE} (assert-equal (list 'c 'd) (list-tail (list 'a 'b 'c 'd) 2)) (assert-equal (list 1 2 3) (list-tail (list 1 2 3) 0)) ``` **See also:** [drop](#drop) --- ## Sequence Helpers {#section-sequence-helpers} Higher-level operations for slicing, chunking, and transforming sequences. These complement the core list operations in the `list` module with lazy-style idioms common in functional programming. ### take {#take} Take first n items. **Signature:** `(take n lst)` **Parameters:** - **`n`** — Number of elements to take - **`lst`** — Source list **Examples:** ```{arl} (take 3 (list 1 2 3 4 5)) ; => (1 2 3) (take 0 (list 1 2 3)) ; => () (take 10 (list 1 2)) ; => (1 2) ``` ```{arl, include=FALSE} (assert-equal (list 1 2 3) (take 3 (list 1 2 3 4 5))) (assert-equal (list) (take 0 (list 1 2 3))) (assert-equal (list 1 2) (take 10 (list 1 2))) ``` **See also:** [drop](#drop), [take-while](#take-while) --- ### drop {#drop} Drop first n items. **Signature:** `(drop n lst)` **Parameters:** - **`n`** — Number of elements to skip - **`lst`** — Source list **Examples:** ```{arl} (drop 2 (list 1 2 3 4 5)) ; => (3 4 5) (drop 0 (list 1 2 3)) ; => (1 2 3) (drop 10 (list 1 2)) ; => () ``` ```{arl, include=FALSE} (assert-equal (list 3 4 5) (drop 2 (list 1 2 3 4 5))) (assert-equal (list 1 2 3) (drop 0 (list 1 2 3))) (assert-equal (list) (drop 10 (list 1 2))) ``` **See also:** [take](#take), [drop-while](#drop-while) --- ### take-while {#take-while} Take items while predicate is true. **Signature:** `(take-while pred lst)` **Parameters:** - **`pred`** — Predicate function; taking stops at first #f - **`lst`** — Source list **Examples:** ```{arl} (take-while odd? (list 1 3 5 2 4)) ; => (1 3 5) (take-while even? (list 1 2 3)) ; => () ``` ```{arl, include=FALSE} (assert-equal (list 1 3 5) (take-while odd? (list 1 3 5 2 4))) (assert-equal (list) (take-while even? (list 1 2 3))) ``` **See also:** [take](#take), [drop-while](#drop-while), [filter](lang-functional.html#filter) --- ### drop-while {#drop-while} Drop items while predicate is true. **Signature:** `(drop-while pred lst)` **Parameters:** - **`pred`** — Predicate function; dropping stops at first #f - **`lst`** — Source list **Examples:** ```{arl} (drop-while odd? (list 1 3 5 2 4)) ; => (2 4) (drop-while even? (list 1 2 3)) ; => (1 2 3) ``` ```{arl, include=FALSE} (assert-equal (list 2 4) (drop-while odd? (list 1 3 5 2 4))) (assert-equal (list 1 2 3) (drop-while even? (list 1 2 3))) ``` **See also:** [drop](#drop), [take-while](#take-while), [filter](lang-functional.html#filter) --- ### partition {#partition} Split list into chunks of size n. **Signature:** `(partition n lst [step n])` **Parameters:** - **`n`** — Chunk size - **`lst`** — Source list - **`step`** — Offset between chunk starts (default n, i.e. no overlap) **Examples:** ```{arl} (partition 2 (list 1 2 3 4 5 6)) ; => ((1 2) (3 4) (5 6)) (partition 3 (list 1 2 3 4 5 6) 2) ; => ((1 2 3) (3 4 5)) (partition 2 (list 1 2 3 4 5)) ; => ((1 2) (3 4)) ``` ```{arl, include=FALSE} (assert-equal (list (list 1 2) (list 3 4) (list 5 6)) (partition 2 (list 1 2 3 4 5 6))) (assert-equal (list (list 1 2) (list 3 4)) (partition 2 (list 1 2 3 4 5))) ``` **See also:** [take](#take), [drop](#drop) --- ### flatten {#flatten} Flatten nested lists. **Signature:** `(flatten lst)` **Parameters:** - **`lst`** — Possibly nested list to flatten into a single-level list **Examples:** ```{arl} (flatten (list 1 (list 2 3) (list 4 (list 5)))) ; => (1 2 3 4 5) (flatten (list 1 2 3)) ; => (1 2 3) ``` ```{arl, include=FALSE} (assert-equal (list 1 2 3 4 5) (flatten (list 1 (list 2 3) (list 4 (list 5))))) (assert-equal (list 1 2 3) (flatten (list 1 2 3))) ``` **See also:** [mapcat](lang-functional.html#mapcat), [append](#append) --- ### repeatedly {#repeatedly} Call fn n times collecting results. **Signature:** `(repeatedly n fn)` **Parameters:** - **`n`** — Number of times to call fn - **`fn`** — Zero-argument function to call repeatedly **Examples:** ```{arl} (repeatedly 3 (lambda () 42)) ; => (42 42 42) ``` ```{arl, include=FALSE} (assert-equal (list 42 42 42) (repeatedly 3 (lambda () 42))) ``` **See also:** [repeat](#repeat), [map](lang-functional.html#map) --- ### repeat {#repeat} Repeat value n times. **Signature:** `(repeat n value)` **Parameters:** - **`n`** — Number of repetitions - **`value`** — Value to repeat **Examples:** ```{arl} (repeat 4 'x) ; => (x x x x) (repeat 3 0) ; => (0 0 0) ``` ```{arl, include=FALSE} (assert-equal (list 'x 'x 'x 'x) (repeat 4 'x)) (assert-equal (list 0 0 0) (repeat 3 0)) ``` **See also:** [repeatedly](#repeatedly) --- ### zip {#zip} Zip lists into list of tuples. **Signature:** `(zip lists...)` **Parameters:** - **`lists`** — Two or more lists to interleave element-wise **Examples:** ```{arl} (zip (list 1 2 3) (list 'a 'b 'c)) ; => ((1 a) (2 b) (3 c)) (zip (list 1 2) (list 'a 'b) (list 'x 'y)) ; => ((1 a x) (2 b y)) ``` ```{arl, include=FALSE} (assert-equal (list (list 1 'a) (list 2 'b) (list 3 'c)) (zip (list 1 2 3) (list 'a 'b 'c))) ``` **See also:** [map](lang-functional.html#map) --- ### member {#member} Return sublist of lst starting at first element equal to x, or #f if not found. Uses equal? by default; pass :use-identical #t for R's identical(). **Signature:** `(member x lst [use-identical #f])` **Parameters:** - **`x`** — Value to search for - **`lst`** — List to search in - **`use-identical`** — Use R's identical() instead of equal? (default #f) **Examples:** ```{arl} (member 3 (list 1 2 3 4 5)) ; => (3 4 5) (member 9 (list 1 2 3)) ; => #f ``` ```{arl, include=FALSE} (assert-equal (list 3 4 5) (member 3 (list 1 2 3 4 5))) (assert-false (member 9 (list 1 2 3))) ``` **See also:** [contains?](#contains-p) --- ### contains? {#contains-p} Return #t if lst contains element equal to x. **Signature:** `(contains? x lst)` **Parameters:** - **`x`** — Value to search for - **`lst`** — List to search in **Examples:** ```{arl} (contains? 2 (list 1 2 3)) ; => #t (contains? 9 (list 1 2 3)) ; => #f ``` ```{arl, include=FALSE} (assert-true (contains? 2 (list 1 2 3))) (assert-false (contains? 9 (list 1 2 3))) ``` **See also:** [member](#member) --- ## Length Predicates {#section-length-predicates} Efficient length comparisons that short-circuit when possible. ### length= {#length-eq} Return #t if length of x equals n. **Signature:** `(length= x n)` **Parameters:** - **`x`** — Sequence to measure - **`n`** — Expected length **Examples:** ```{arl} (length= (list 1 2 3) 3) ; => #t (length= (list 1 2) 3) ; => #f ``` ```{arl, include=FALSE} (assert-true (length= (list 1 2 3) 3)) (assert-false (length= (list 1 2) 3)) ``` **See also:** [length>](#length-gt), [length<](#length-lt), [empty?](lang-types.html#empty-p) --- ### length> {#length-gt} Return #t if length of x is greater than n. **Signature:** `(length> x n)` **Parameters:** - **`x`** — Sequence to measure - **`n`** — Length to compare against **Examples:** ```{arl} (length> (list 1 2 3) 2) ; => #t (length> (list 1 2) 3) ; => #f ``` ```{arl, include=FALSE} (assert-true (length> (list 1 2 3) 2)) (assert-false (length> (list 1 2) 3)) ``` **See also:** [length=](#length-eq), [length<](#length-lt) --- ### length< {#length-lt} Return #t if length of x is less than n. **Signature:** `(length< x n)` **Parameters:** - **`x`** — Sequence to measure - **`n`** — Length to compare against **Examples:** ```{arl} (length< (list 1 2) 3) ; => #t (length< (list 1 2 3) 2) ; => #f ``` ```{arl, include=FALSE} (assert-true (length< (list 1 2) 3)) (assert-false (length< (list 1 2 3) 2)) ``` **See also:** [length=](#length-eq), [length>](#length-gt) --- ## Search and Deduplication {#section-search-and-deduplication} Functions for finding elements and removing duplicates. ### find {#find} Return first element matching predicate, or #f if not found. **Signature:** `(find pred lst)` **Parameters:** - **`pred`** — Predicate function to test each element - **`lst`** — List to search **Examples:** ```{arl} (find even? (list 1 3 4 5)) ; => 4 (find even? (list 1 3 5)) ; => #f ``` ```{arl, include=FALSE} (assert-equal 4 (find even? (list 1 3 4 5))) (assert-false (find even? (list 1 3 5))) ``` **See also:** [member](#member), [contains?](#contains-p), [filter](lang-functional.html#filter) --- ### distinct {#distinct} Remove duplicates preserving first-occurrence order. Uses R's identical() for comparison. **Signature:** `(distinct lst)` **Parameters:** - **`lst`** — List to deduplicate **Examples:** ```{arl} (distinct (list 1 2 1 3 2)) ; => (1 2 3) ``` ```{arl, include=FALSE} (assert-equal (list 1 2 3) (distinct (list 1 2 1 3 2))) ``` **See also:** [filter](lang-functional.html#filter) --- ## Splitting {#section-splitting} Functions for splitting sequences at positions or predicates. ### split-at {#split-at} Split list into two parts at index n. Returns a list of (take n lst) and (drop n lst). **Signature:** `(split-at n lst)` **Parameters:** - **`n`** — Index to split at - **`lst`** — List to split **Examples:** ```{arl} (split-at 2 (list 'a 'b 'c 'd)) ; => ((a b) (c d)) ``` ```{arl, include=FALSE} (assert-equal (list (list 1 2) (list 3 4)) (split-at 2 (list 1 2 3 4))) ``` **See also:** [split-with](#split-with), [take](#take), [drop](#drop) --- ### split-with {#split-with} Split list into two parts: elements satisfying pred at the start, and the rest. Returns (take-while pred lst) and (drop-while pred lst). **Signature:** `(split-with pred lst)` **Parameters:** - **`pred`** — Predicate function - **`lst`** — List to split **Examples:** ```{arl} (split-with even? (list 2 4 1 3)) ; => ((2 4) (1 3)) ``` ```{arl, include=FALSE} (assert-equal (list (list 2 4) (list 1 3)) (split-with even? (list 2 4 1 3))) ``` **See also:** [split-at](#split-at), [take-while](#take-while), [drop-while](#drop-while) --- ### interpose {#interpose} Insert separator between every element of list. **Signature:** `(interpose sep lst)` **Parameters:** - **`sep`** — Value to insert between elements - **`lst`** — List to interpose into **Examples:** ```{arl} (interpose 0 (list 1 2 3)) ; => (1 0 2 0 3) ``` ```{arl, include=FALSE} (assert-equal (list 1 0 2 0 3) (interpose 0 (list 1 2 3))) ``` **See also:** [flatten](#flatten) --- ### partition-by {#partition-by} Split list into runs of consecutive elements producing the same key. Different from partition which splits by size. **Signature:** `(partition-by fn lst)` **Parameters:** - **`fn`** — Key function applied to each element - **`lst`** — List to partition **Examples:** ```{arl} (partition-by even? (list 2 4 1 3 6)) ; => ((2 4) (1 3) (6)) ``` ```{arl, include=FALSE} (assert-equal (list (list 2 4) (list 1 3) (list 6)) (partition-by even? (list 2 4 1 3 6))) ``` **See also:** [partition](#partition), [split-with](#split-with) --- ## Sorting {#section-sorting} General-purpose sorting with user-supplied comparator functions. `list-sort` uses quicksort (not stable); `stable-sort` uses merge sort and preserves the relative order of equal elements. `merge-sorted` combines two already-sorted lists. ### list-sort {#list-sort} Sort list using comparison function (simple quicksort implementation). **Signature:** `(list-sort lst comparator)` **Parameters:** - **`lst`** — List to sort - **`comparator`** — Binary predicate returning #t when first arg should come before second **Examples:** ```{arl} (list-sort (list 3 1 4 1 5) <) ; => (1 1 3 4 5) (list-sort (list "b" "a" "c") (lambda (a b) (< a b))) ; => ("a" "b" "c") ``` ```{arl, include=FALSE} (assert-equal (list 1 1 3 4 5) (list-sort (list 3 1 4 1 5) <)) ``` **See also:** [stable-sort](#stable-sort), [sort-by](#sort-by) --- ### sort-by {#sort-by} Sort list by applying key-fn to each element, then comparing. **Signature:** `(sort-by lst key-fn comparator)` **Parameters:** - **`lst`** — List to sort - **`key-fn`** — Function to extract a comparison key from each element - **`comparator`** — Binary predicate applied to extracted keys **Examples:** ```{arl} (sort-by (list (list "b" 2) (list "a" 1)) car (lambda (a b) (< a b))) ; => (("a" 1) ("b" 2)) (sort-by (list 3 -1 2) abs <) ; => (-1 2 3) ``` ```{arl, include=FALSE} (assert-equal (list -1 2 3) (sort-by (list 3 -1 2) abs <)) ``` **See also:** [list-sort](#list-sort), [stable-sort](#stable-sort) --- ### merge-sorted {#merge-sorted} Merge two sorted lists into one sorted list. Stable: when elements are equal (neither comparator direction is true), takes from list1 first. **Signature:** `(merge-sorted list1 list2 comparator)` **Parameters:** - **`list1`** — First sorted list - **`list2`** — Second sorted list - **`comparator`** — Binary predicate used to order elements **Examples:** ```{arl} (merge-sorted (list 1 3 5) (list 2 4 6) <) ; => (1 2 3 4 5 6) (merge-sorted (list 1 2) (list) <) ; => (1 2) ``` ```{arl, include=FALSE} (assert-equal (list 1 2 3 4 5 6) (merge-sorted (list 1 3 5) (list 2 4 6) <)) (assert-equal (list 1 2) (merge-sorted (list 1 2) (list) <)) ``` **See also:** [stable-sort](#stable-sort), [list-sort](#list-sort) --- ### stable-sort {#stable-sort} Stable sort - preserves order of equal elements. Uses merge sort internally. **Signature:** `(stable-sort lst comparator)` **Parameters:** - **`lst`** — List to sort - **`comparator`** — Binary predicate returning #t when first arg should come before second **Examples:** ```{arl} (stable-sort (list 3 1 4 1 5) <) ; => (1 1 3 4 5) ``` ```{arl, include=FALSE} (assert-equal (list 1 1 3 4 5) (stable-sort (list 3 1 4 1 5) <)) ``` **Note:** Preserves the relative order of elements that compare equal, unlike `list-sort`. **See also:** [list-sort](#list-sort), [merge-sorted](#merge-sorted), [sort-by](#sort-by) ---