ilusm.dev
Guide

Working with Lists

List literals, indexing, loops, and the full trl module - map, filter, fold, sort, and everything in between.

List basics

Lists are ordered collections. Items can be any type. Zero-indexed.

xs = [1, 2, 3]
mixed = [1, "two", tru, nil]

prn xs[0]      # 1
prn xs[2]      # 3
prn len(xs)    # 3

xs[1] = 99     # mutate in place
prn xs         # [1, 99, 3]

Empty list is falsy

if []:  prn "never"
if [0]: prn "truthy - list has one item"

Looping over a list

xs = ["a", "b", "c"]

x <- xs:
    prn x    # a, b, c

With brk and cnt:

x <- xs:
    if x == "b": cnt   # skip "b"
    prn x              # a, c

The trl module

Load with use trl. All list transform functions live here.

Map - transform each item

use trl

dbl(x) = x * 2
trl.map([1, 2, 3], dbl)          # [2, 4, 6]
trl.map([1, 2, 3], \(x) x * 2)  # [2, 4, 6]

Filter - keep matching items

trl.fil([1, -2, 3, -4], \(x) x > 0)   # [1, 3]

Fold - reduce to a single value

trl.fld([1, 2, 3, 4], 0, \(acc, x) acc + x)   # 10 (sum)
trl.fld([1, 2, 3, 4], 1, \(acc, x) acc * x)   # 24 (product)

Find - search for items

trl.sel([1, 2, 3], \(x) x > 1)   # 2  (first match)
trl.idx([1, 2, 3], \(x) x == 2)  # 1  (index of match, -1 if none)
trl.any([1, 2, 3], \(x) x > 2)  # tru
trl.all([1, 2, 3], \(x) x > 0)  # tru
trl.tly([1, 2, 3], \(x) x > 1)  # 2  (count of matches)

Sort, reverse, unique

trl.srt([3, 1, 2])           # [1, 2, 3]
trl.srt(["b", "a", "c"])     # ["a", "b", "c"]
trl.rev([1, 2, 3])           # [3, 2, 1]
trl.unq([1, 2, 1, 3, 2])     # [1, 2, 3]

Concat, slice, and remove last

trl.cat([1, 2], [3, 4])     # [1, 2, 3, 4]
trl.but([1, 2, 3])          # [1, 2]  (all but last)
trl.take([1, 2, 3, 4], 2)   # [1, 2]  (first n)
trl.drop([1, 2, 3, 4], 2)   # [3, 4]  (skip first n)
trl.slc([1,2,3,4,5], 1, 3)  # [2, 3]  (slice start..end exclusive)

Aggregates

trl.sum([1, 2, 3, 4])       # 10
trl.max([3, 1, 4, 1, 5])    # 5
trl.min([3, 1, 4, 1, 5])    # 1
trl.has([1, 2, 3], 2)       # tru  (contains value?)
trl.shuf([1, 2, 3, 4])      # shuffled copy (random order)

Flat map - map then flatten

trl.flm([[1, 2], [3, 4]], \(x) x)   # [1, 2, 3, 4]
trl.flm(["hi", "bye"], \(s) txt.lst(s))  # ["h","i","b","y","e"]

Group by

items = [{n: "alice", dep: "eng"}, {n: "bob", dep: "eng"}, {n: "carol", dep: "hr"}]
trl.grp(items, \(x) x.dep)
# {eng: [{n:"alice",...}, {n:"bob",...}], hr: [{n:"carol",...}]}

Zip - pair two lists

trl.zip([1, 2, 3], ["a", "b", "c"])
# [[1,"a"], [2,"b"], [3,"c"]]

Side effects

trl.eac([1, 2, 3], \(x) prn x)   # prints each, returns nil

Pipeline syntax

Use | to pipe lists through transforms. Stage names after | don't need trl.:

use trl

[3, 1, 4, 1, 5] | trl.srt         # [1, 1, 3, 4, 5]
[3, 1, 4, 1, 5] | srt              # same, short form

xs = [1, -2, 3, -4, 5]
xs | fil \(x) x > 0 | map \(x) x * 10 | srt
# [10, 30, 50]

Common patterns

Sum a list of numbers

use trl
total = trl.fld([1, 2, 3, 4, 5], 0, \(a, x) a + x)   # 15

Extract a field from a list of objects

use trl
users = [{name: "alice", age: 30}, {name: "bob", age: 25}]
names = trl.map(users, \(u) u.name)   # ["alice", "bob"]

Remove duplicates and sort

use trl
tags = ["go", "ilusm", "go", "rust", "ilusm"]
tags | unq | srt   # ["go", "ilusm", "rust"]

Check if any item passes a condition

use trl
scores = [42, 91, 67, 88]
trl.any(scores, \(s) s >= 90)   # tru