tur/list
typed singly-linked List[A] with Cons cells.
Since: Phase TC1-B
Cons
(defstruct Cons [A])
parameterized cons cell with typed head and tail.
Since: Phase TC1
tcons
(tcons [A])
prepend a value to a typed list.
| h | head element of type A | |
| t | tail list (another typed list or tnil) |
A new (Cons A) cell with h at the front. The head slot is laid out as A's concrete C type (e.g. a `double` field for a float head), exactly like `tcons-of`. A (Cons A) carrier coerces to the :int carrier in argument position, so the result still composes with the list-head/list-tail walkers and the carrier-level list helpers (nest (tcons x (tcons ...)) just like before).
(tcons 1 (tcons 2 (tnil))) ; => (Cons int) [1, 2] (tcons 1.5 (tnil)) ; => (Cons float) double-headed cell
Since: Phase TC1
tcons-of
(tcons-of [A])
typed Cons[A] constructor with a typed head slot.
| h | head element of type A | |
| t | tail link (carrier :int; pass another cell's pointer or 0 for tnil) |
A (Cons A) value whose head field is laid out as the concrete C type for A (e.g. `double` for `:float`), with no user-side bit-cast.
(let [c (tcons-of 1.5 0)]
(.head c)) ; => 1.5, read as a `double` field
Since: Phase TS3
tnil
(tnil :)
return an empty typed list.
0, representing the empty List[A].
(tnil) ; => empty list
Since: Phase TC1
tnil?
(tnil? [l : int] :)
check whether a typed list is empty.
| l | List[A] |
true if l is the empty list, false otherwise.
(tnil? (tnil)) ; => true (tnil? (tcons 1 (tnil))) ; => false
Since: Phase TC1
thead
(thead [A])
return the head element of a non-empty typed list.
| l | Cons[A] |
The head element of type A.
(let [l (:: (make-struct Cons 42 (tnil)) (Cons int))]
(thead l)) ; => 42
Since: Phase TC1
ttail
(ttail [A])
return the tail carrier of a non-empty typed list.
| l | Cons[A] |
The tail list carrier.
(let [l (:: (make-struct Cons 1 (tnil)) (Cons int))]
(ttail l)) ; => 0
Since: Phase TC1
tlength
(tlength [A])
count the elements of a typed (Cons A) list.
| xs | the (Cons A) list to measure |
Integer length.
(tlength (:: (list (some 1) (some 2)) (Cons (Option int)))) ; => 2
Since: Phase G4 (carrier<->concrete ABI crossing audit)
list-length
(list-length [l : int])
count the number of elements in a typed list.
| l | List[A] |
Integer length.
(list-length (list 1 2)) ; => 2
Since: Phase TC1
list-eq?
(list-eq? [l1 : int l2 : int ^fat cmp-fn : (fn [int int])
compare two typed lists element-wise.
| l1 | first List[A] | |
| l2 | second List[A] | |
| cmp-fn | comparator fn [a :int b :int] :bool |
true if both lists have the same elements in the same order.
(list-eq? (list 1) (list 1) (fn [a b] (= a b))) ; => true
Since: Phase TC1
cons-eq-go
(cons-eq-go [A])
by-value structural equality walk over two non-nil (Cons A) cells.
| c1 | first head cell, a non-nil (Cons A) | |
| c2 | second head cell, a non-nil (Cons A) |
true when both chains have equal heads in the same order and equal length.
(cons-eq-go (:: (tcons 1 (tnil)) (Cons int))
(:: (tcons 1 (tnil)) (Cons int))) ; => true
Since: Phase TCE (typed-collection-eq-consumers)
Eq[Cons]
(definstance Eq [Cons])
element-wise equality using the element type's Eq instance.
tur-list-homog__
(tur-list-homog__ [A])
internal: compile-time element homogeneity check.
list-homog-chain__
(list-homog-chain__ [& xs])
internal: pairwise-chain tur-list-homog__ over xs.
list-build__
(list-build__ [& xs])
internal: right-fold xs into a typed (tcons-of ...) chain.
list
(list [& xs])
construct a typed list from N values via nested tcons-of.
| & xs -- zero or more values, all of a single element type A. |
The right-folded (tcons-of ... (tnil)) chain, typed as (Cons A) where A is the element type recovered from the literal -- so (list 7.1 2.5) is a (Cons float) whose head slot is a `double`, and (list 1 2 3) is a (Cons int). A (Cons A) carrier coerces to :int in argument position, so the result still composes with list-length, list-eq?, and the rest of the :int-taking carrier API; an empty (list) is the bare :int carrier 0. Note: all elements must unify to a single type. Mixing types -- e.g. (list 1 "x" 3.14) -- is a type error (TUR-E0001 on the offending element). That genuinely-heterogeneous case is the one place to reach for tuple2, tuple3, tuple4, or tuple5 instead; a homogeneous non-int list (like a float list) is exactly what this macro now builds directly.
(list) ; => (tnil), carrier 0 (list 1 2 3) ; => (Cons int): tcons-of 1 (tcons-of 2 (tcons-of 3 (tnil))) (list 7.1 2.5) ; => (Cons float): a double-headed cons chain ; Heterogeneous -- type error: ; (list 1 "x") ; => TUR-E0001: expected int, got cstr; use tuple2 instead
Since: List literal macro
list*
(list* [& args])
prepend values onto an existing list tail.
| & args -- one or more arguments; the last is the existing tail list, | ||
| prior arguments are prepended left-to-right. |
The right-folded (tcons-of ... tail) chain where tail is the last argument. With a single argument, returns it unchanged (identity on the tail). Routing through the polymorphic-head tcons-of means a non-int prefix (e.g. a float) specializes its head slot, mirroring (list ...). Note: each prefix element pins its own cons cell's head type; the prefix elements should share the tail's element type. A (Cons A) tail coerces to the :int tail carrier, so the chain composes with the carrier list API. For genuinely heterogeneous needs, use tupleN.
(list* (tnil)) ; => (tnil) (list* 1 2 (tnil)) ; => (tcons-of 1 (tcons-of 2 (tnil))) (list* 1 2 (list 3 4)) ; => (Cons int) of 1 2 3 4 (list* 7.1 (list 2.5)) ; => (Cons float) of 7.1 2.5
Since: List literal macro
list-head
(list-head [l : int] :)
head element of a non-empty carrier-level list.
list-tail
(list-tail [l : int] :)
tail pointer of a non-empty carrier-level list.
list-concat
(list-concat [l1 : int l2 : int] :)
concatenate two lists.
| l1 | first List[A] | |
| l2 | second List[A] |
A new list with all elements of l1 followed by all elements of l2. Returns l2 directly when l1 is empty (no allocation). Note: l1 and l2 elements must share the same type (all :int at carrier level). An empty l1 returns l2 directly (no allocation). This function is a prerequisite for unquote-splicing in list-quasiquote-plan.md; the N-ary signature should be preserved.
(list-concat (list) (list 1 2)) ; => (list 1 2) (list-concat (list 1 2) (list)) ; => (list 1 2) (list-concat (list 1 2) (list 3 4)) ; => (list 1 2 3 4)
Since: List literal macro
car
(car [l : int] :)
head of a cons-built list (classic-Lisp alias for list-head).
| l | a non-empty carrier-level list (e.g. built with cons or list) |
The head element (carrier :int).
(car (cons 11 (cons 22 (tnil)))) ; => 11
Since: Phase TC1
cdr
(cdr [l : int] :)
tail of a cons-built list (classic-Lisp alias for list-tail).
| l | a non-empty carrier-level list (e.g. built with cons or list) |
The tail list (carrier :int; 0 when l had a single element).
(car (cdr (cons 11 (cons 22 (tnil))))) ; => 22
Since: Phase TC1
null?
(null? [l : int] :)
test a cons-built list for emptiness (alias for tnil?).
| l | a carrier-level list |
true when l is the empty list, false otherwise.
(null? (tnil)) ; => true (null? (cons 1 (tnil))) ; => false
Since: Phase TC1
length
(length [l : int] :)
count the elements of a cons-built list (alias for list-length).
| l | a carrier-level list |
Integer length.
(length (list 1 2 3)) ; => 3
Since: Phase TC1
Internal definitions
__cons-fmap-- apply a typed thunk to every head element of a Cons list.