Cookbook

Short recipes for everyday tasks. Every snippet runs as-is — paste it into a file and citril it, or try it in the REPL.

Lists

Build and transform

let xs = range(1, 6)            # [1, 2, 3, 4, 5]
let squares = map(function(x) return x * x end, xs)
let big = filter(function(x) return x > 5 end, squares)
print(squares)                  # [1, 4, 9, 16, 25]
print(big)                      # [9, 16, 25]

Sum, min, and max

let xs = [4, 1, 7, 3]
print(sum(xs))    # 15
print(min(xs))    # 1
print(max(xs))    # 7

Sort ascending or with a comparator

print(sort([3, 1, 2]))                                   # [1, 2, 3]
print(sort([3, 1, 2], function(a, b) return a > b end))  # [3, 2, 1]  (descending)

Use a list as a stack

let stack = []
push(stack, "a")
push(stack, "b")
print(pop(stack))    # b
print(stack)         # ["a"]

Slice and index

let xs = [10, 20, 30, 40, 50]
print(xs[0])         # 10   (first)
print(xs[-1])        # 50   (last)
print(slice(xs, 1, 3))  # [20, 30]   (from index 1 up to, not including, 3)

Enumerate and zip

for pair in enumerate(["a", "b", "c"]) do
  print("${pair[0]}: ${pair[1]}")   # 0: a / 1: b / 2: c
end

let names = ["Ada", "Alan"]
let years = [1815, 1912]
print(zip(names, years))   # [["Ada", 1815], ["Alan", 1912]]

Maps

Create, read, and update

let user = { name: "Ada", visits: 0 }
user.visits += 1
user["role"] = "admin"     # add a new key
print(user.name)           # Ada
print(has(user, "role"))   # true
delete(user, "visits")     # remove a key

Iterate over a map

let scores = { ada: 92, alan: 88 }
for key in keys(scores) do
  print("${key} -> ${scores[key]}")
end

for pair in items(scores) do
  print("${pair[0]} = ${pair[1]}")
end

Count occurrences

let words = ["red", "blue", "red", "green", "red"]
let tally = {}
for w in words do
  if has(tally, w) then
    tally[w] += 1
  else
    tally[w] = 1
  end
end
print(tally)   # {"red": 3, "blue": 1, "green": 1}

Strings

Interpolate and format

let name = "Ada"
let n = 3
print("Hello, ${name}! ${n} + ${n} = ${n + n}")
print("a literal dollar: \${not interpolated}")   # single quotes are literal too

Split and join

let csv = "ada,alan,grace"
let parts = split(csv, ",")     # ["ada", "alan", "grace"]
print(join(parts, " | "))       # ada | alan | grace

Trim, change case, and test

print(trim("  hi  "))              # hi
print(upper("citril"))             # CITRIL
print(capitalize("citril"))        # Citril
print(starts_with("citril", "cit"))  # true
print(replace("hello", "l", "L"))  # heLLo

Numbers and math

Convert between types

print(int("42") + 1)      # 43
print(float("3.14"))      # 3.14
print(str(2026))          # "2026"
print(parse_int("ff", 16))  # 255

Round, clamp, and random

print(round(3.14159, 2))   # 3.14
print(clamp(120, 0, 100))  # 100
print(pow(2, 10))          # 1024
print(sqrt(144))           # 12
print(randint(1, 6))       # a dice roll

Control & errors

Guard against bad input

function reciprocal(x)
  if x == 0 then
    error("reciprocal of zero is undefined")
  end
  return 1 / x
end

try
  print(reciprocal(0))
catch e
  print("error: ${e}")   # error: reciprocal of zero is undefined
end

Dispatch on type

function describe(v)
  if is_number(v) then return "a number"
  elif is_string(v) then return "a string"
  elif is_list(v) then return "a list of ${len(v)}"
  else return type(v)
  end
end

print(describe(42))        # a number
print(describe([1, 2, 3])) # a list of 3

Time a block of code

let start = clock()
let total = reduce(function(a, b) return a + b end, range(1, 100000), 0)
print("sum = ${total} in ${round((clock() - start) * 1000, 1)} ms")

Looking for a specific function? The Standard library lists all ~75 built-ins by topic.