ListsealedThe ordered, growable sequence — Quoin's workhorse collection, written #(10 20 30).
Indexes are zero-based. A list holds any mix of values; one checked to a single element class comes from List.of: / ensure:. The natives here are the storage primitives; the wider iteration surface (each:, collect:, select:, …) is the Iterate mixin in the standard library, built on them.
Lists are iterable in index order, and element-preserving combinators answer .emptyLike collections so a checked List(T) stays checked.
Parallel combinators on List: parallelCollect: / parallelReduce: map and fold across the shared Parallel worker pool, preserving order.
A fresh empty List, the List class default.
A fresh empty list — the same value the #() literal builds.
List.new.count "* -> 0
Always refused: a List has no instance fields for a new: config block to set. Construct with #(), List.new, or List.of:.
A fresh empty list tagged with an element class: every later insert is checked, so an add: / at:put: of a non-matching value raises a catchable TypeError.
(List.of:Integer).add:1 "* -> #(1)
Element-wise equality: true when the other value is a List of the same length whose elements are pairwise ==. Anything that is not a List answers false.
#(1 2 3) == #(1 2 3) "* -> true
Append a value at the end; answers the receiver, so adds chain. On a tagged list (List.of:) the value is checked first.
#(1 2).add:3 "* -> #(1 2 3)
The element at a zero-based index; any out-of-range index (negatives included) answers nil.
#(10 20 30).at:1 "* -> 20
Replace the element at a zero-based index; answers the receiver. An out-of-range index raises a catchable IndexError — unlike at:, writing never extends the list. On a tagged list (List.of:) the value is checked first.
#(1 2 3).at:1 put:99 "* -> #(1 99 3)
Destructure into a block: call it with the list's elements as its arguments — a two-parameter block gets the first two elements, extras are ignored. Answers the block's value.
#(3 4).bind:{ |w h| w * h } "* -> 12
Element-preserving combinators on a List accumulate into .emptyLike, keeping any element-type check.
The number of elements.
#(10 20 30).count "* -> 3
Call the block once per element, in index order.
var t = 0; #(1 2 3).each:{ |x| t = t + x }; t "* -> 6
The checked element type as a Symbol, or nil for an ordinary untagged list.
(List.of:Integer).elementType "* -> Integer
A fresh empty list like the receiver — element tag included. The species hook the Iterate mixin uses, so transforms of a checked list stay checked.
Check every element against a class and answer a NEW list carrying that element tag; a non-matching element raises a catchable TypeError. The receiver is copied, not retagged in place, so other holders of the untagged list are unaffected.
(#(1 2 3).ensure:Integer).elementType "* -> Integer
One string from the elements' .s renderings with the separator between them. The separator only appears while the accumulated result is non-empty, so an empty leading piece adds nothing.
#(1 2 3).join:', ' "* -> 1, 2, 3
Order-preserving parallel map. The block must be portable (read-only data captures; no writes to outer bindings, no self/@fields, no ^^) — violations raise the portability error, catchable at the call site. Inputs shorter than Parallel.minItems (and calls made from inside a worker) run serially, with the same result.
#(1 2 3).parallelCollect:{ |x| x * 10 } "* -> #(10 20 30)
Parallel semigroup fold, mirroring reduce: (no seed): the block combines two values into one and MUST be associative — each worker folds its chunk, then the partials fold on this side. Non-associative blocks get chunk-boundary-dependent answers; that's on the caller, exactly as documented.
#(1 2 3 4).parallelReduce:{ |a b| a + b } "* -> 10
Insert a value at the front (index 0); answers the receiver. The end-of-list counterpart is add:.
#(2 3).push:1 "* -> #(1 2 3)
The display string: #( and ) around each element's .s, space-separated.
#(1 'two' 3).s "* -> #(1 two 3)
A new list of the elements from a zero-based index to the end; an index past the end answers #(). A checked receiver's element tag carries over.
#(10 20 30 40).sliceFrom:2 "* -> #(30 40)
A new list of the elements from a zero-based start index to an exclusive end index, both clamped to the list's bounds (an empty or inverted range answers #()). A checked receiver's element tag carries over.
#(10 20 30 40).sliceFrom:1 to:3 "* -> #(20 30)
Sort in place, ascending by the elements' >:, and answer the receiver; nils sort last.
#(3 1 2).sort "* -> #(1 2 3)
Sort in place, directed by the block, and answer the receiver. A one-parameter block is a KEY: elements are ordered by their keys' >:, ascending. A two-parameter block is a COMPARATOR: it answers true when its arguments are already in order.
#('bb' 'a' 'ccc').sort:{ |x| x.length } "* -> #(a bb ccc) #(3 1 2).sort:{ |a b| a >= b } "* -> #(3 2 1)