Lowbar
A comprehensive utility plugin for ARO.
Qualifiers and actions for working with collections, objects, and values
— expressed in plain language, not callbacks.
With thanks to the Underscore.js community,
whose work inspired Lowbar's API design.
71 Qualifiers
5 Actions
Swift Plugin
v1.0.0
ARO is a declarative language where operations read like business requirements.
Lowbar extends ARO's vocabulary with the utility functions you reach for every day
— filtering collections, reshaping objects, checking types, generating sequences —
all accessible through ARO's qualifier syntax.
(* Find all active admins and extract their names *)
Create the <users> with [
{ name: "Alice", role: "admin", active: true },
{ name: "Bob", role: "user", active: true },
{ name: "Eve", role: "admin", active: false }
].
Compute the <active-admins: lowbar.where> from the <users> with { role: "admin", active: true }.
Compute the <names: lowbar.pluck> from the <active-admins> with { field: "name" }.
(* names = ["Alice"] *)
Installation
Add Lowbar to your ARO project with a single command:
aro add https://github.com/arolang/Lowbar.git
Or copy the Plugins/lowbar/ directory manually into your application's
Plugins/ folder. Either way, ARO discovers and compiles the plugin
automatically on first run.
Your application should look like this:
MyApp/
├── main.aro
└── Plugins/
└── lowbar/
├── plugin.yaml
├── Package.swift
└── Sources/
└── LowbarPlugin.swift
Requires Swift 5.9+ and the ARO Plugin SDK.
How It Works
Lowbar provides two kinds of tools: qualifiers that transform values inline,
and actions that generate new data.
Qualifiers
Qualifiers transform a value using the <result: lowbar.qualifier> syntax.
They read naturally as part of an ARO statement:
Compute the <reversed: lowbar.reverse> from the <items>.
Many qualifiers accept parameters through a with { } clause:
Compute the <top-three: lowbar.first> from the <items> with { n: 3 }.
Compute the <sorted: lowbar.sort-by> from the <users> with { field: "age" }.
Qualifiers also work inside expressions, applied directly to a variable:
Log <items: lowbar.reverse> to the <console>.
Actions
Actions are verb-based statements using the Lowbar. prefix (PascalCase handle):
Lowbar.Range the <numbers> with { stop: 10 }.
Lowbar.Random the <dice> with { min: 1, max: 6 }.
Collections
Functions for working with lists. These qualifiers let you slice, filter, reorder,
and reshape collections with a single statement.
first
Compute the <result: lowbar.first> from the <list>.
Returns the first element of a list. Pass n to get the first N elements instead.
Useful for peeking at the head of a collection or taking a fixed-size prefix.
Create the <items> with [5, 3, 8, 1, 9].
Compute the <head: lowbar.first> from the <items>.
(* head = 5 *)
Compute the <top-three: lowbar.first> from the <items> with { n: 3 }.
(* top-three = [5, 3, 8] *)
initial
Compute the <result: lowbar.initial> from the <list>.
Returns everything except the last element. Pass n to exclude the last N elements.
The complement of last.
Compute the <without-tail: lowbar.initial> from [1, 2, 3, 4, 5].
(* without-tail = [1, 2, 3, 4] *)
Compute the <trimmed: lowbar.initial> from [1, 2, 3, 4, 5] with { n: 3 }.
(* trimmed = [1, 2] *)
last
Compute the <result: lowbar.last> from the <list>.
Returns the last element of a list. Pass n to get the last N elements.
The mirror of first.
Compute the <tail: lowbar.last> from [1, 2, 3, 4, 5].
(* tail = 5 *)
Compute the <last-two: lowbar.last> from [1, 2, 3, 4, 5] with { n: 2 }.
(* last-two = [4, 5] *)
rest
Compute the <result: lowbar.rest> from the <list>.
Returns everything except the first element. Pass n to skip the first N elements.
The complement of first.
Compute the <remaining: lowbar.rest> from [1, 2, 3, 4, 5].
(* remaining = [2, 3, 4, 5] *)
Compute the <after-third: lowbar.rest> from [1, 2, 3, 4, 5] with { n: 3 }.
(* after-third = [4, 5] *)
compact
Compute the <result: lowbar.compact> from the <list>.
Strips all falsy values from a list: nil, false,
0, and empty strings are removed. Everything else stays.
Handy for cleaning up data before processing.
Create the <messy> with [0, 1, "", "hello", false, true, 42].
Compute the <clean: lowbar.compact> from the <messy>.
(* clean = [1, "hello", true, 42] *)
flatten
Compute the <result: lowbar.flatten> from the <list>.
Flattens a nested list into a single level. Deep flattening is the default — all
nesting is unwound. Pass deep: false to flatten only one level.
Create the <nested> with [[1, 2], [3, [4, 5]], [6]].
Compute the <flat: lowbar.flatten> from the <nested>.
(* flat = [1, 2, 3, 4, 5, 6] *)
Compute the <shallow: lowbar.flatten> from the <nested> with { deep: false }.
(* shallow = [1, 2, 3, [4, 5], 6] *)
uniq
Compute the <result: lowbar.uniq> from the <list>.
Removes duplicate values, preserving first-seen order. For lists of objects,
pass field to deduplicate by a specific property.
Compute the <unique: lowbar.uniq> from [1, 2, 2, 3, 3, 3].
(* unique = [1, 2, 3] *)
Create the <records> with [
{ id: 1, role: "admin" },
{ id: 2, role: "user" },
{ id: 3, role: "admin" }
].
Compute the <by-role: lowbar.uniq> from the <records> with { field: "role" }.
(* by-role = [{id: 1, role: "admin"}, {id: 2, role: "user"}] *)
shuffle
Compute the <result: lowbar.shuffle> from the <list>.
Returns a randomly reordered copy using the Fisher-Yates algorithm. Also works on
strings, shuffling individual characters.
Compute the <shuffled: lowbar.shuffle> from [1, 2, 3, 4, 5].
(* shuffled = [3, 1, 5, 2, 4] (random) *)
Compute the <anagram: lowbar.shuffle> from "hello".
(* anagram = "lhoel" (random) *)
sample
Compute the <result: lowbar.sample> from the <list>.
Draws a random element from the list. Pass n to draw multiple
elements without replacement.
Compute the <winner: lowbar.sample> from ["alice", "bob", "eve"].
(* winner = "bob" (random) *)
Compute the <team: lowbar.sample> from ["alice", "bob", "eve"] with { n: 2 }.
(* team = ["eve", "alice"] (random) *)
size
Compute the <result: lowbar.size> from the <value>.
Returns the number of elements in a list, characters in a string, or keys in an object.
A universal length check.
Compute the <count: lowbar.size> from [10, 20, 30].
(* count = 3 *)
Compute the <len: lowbar.size> from "hello".
(* len = 5 *)
Compute the <fields: lowbar.size> from { host: "localhost", port: 8080 }.
(* fields = 2 *)
reverse
Compute the <result: lowbar.reverse> from the <value>.
Reverses the order of elements in a list, or characters in a string.
Compute the <backwards: lowbar.reverse> from [1, 2, 3].
(* backwards = [3, 2, 1] *)
Compute the <flipped: lowbar.reverse> from "ARO".
(* flipped = "ORA" *)
to-array
Compute the <result: lowbar.to-array> from the <value>.
Converts a value to a list. Strings become character arrays, objects become their values.
Lists pass through unchanged.
Compute the <chars: lowbar.to-array> from "Hi".
(* chars = ["H", "i"] *)
Compute the <vals: lowbar.to-array> from { a: 1, b: 2 }.
(* vals = [1, 2] *)
Searching
Find elements by matching properties, check membership, and locate positions.
Instead of callback predicates, Lowbar matches against the properties you provide in the
with { } clause.
where
Compute the <result: lowbar.where> from the <list> with { key: value, ... }.
Filters a list of objects, keeping only those whose properties match every
key-value pair in the with clause. The declarative alternative to writing
filter callbacks.
Create the <users> with [
{ name: "Alice", role: "admin", active: true },
{ name: "Bob", role: "user", active: true },
{ name: "Eve", role: "admin", active: false }
].
Compute the <admins: lowbar.where> from the <users> with { role: "admin" }.
(* admins = [{name: "Alice", ...}, {name: "Eve", ...}] *)
Compute the <active-admins: lowbar.where> from the <users> with { role: "admin", active: true }.
(* active-admins = [{name: "Alice", ...}] *)
find-where
Compute the <result: lowbar.find-where> from the <list> with { key: value }.
Returns the first object in the list that matches all given properties.
When you only need one match, this is faster and more direct than where.
Compute the <first-admin: lowbar.find-where> from the <users> with { role: "admin" }.
(* first-admin = {name: "Alice", role: "admin", active: true} *)
reject-where
Compute the <result: lowbar.reject-where> from the <list> with { key: value }.
The inverse of where. Returns every object that does not match
the given properties.
Compute the <non-admins: lowbar.reject-where> from the <users> with { role: "admin" }.
(* non-admins = [{name: "Bob", role: "user", active: true}] *)
contains
Compute the <result: lowbar.contains> from the <list> with { value: x }.
Returns true if the given value is present in the list.
Compute the <has-it: lowbar.contains> from [1, 2, 3] with { value: 2 }.
(* has-it = true *)
every
Compute the <result: lowbar.every> from the <list> with { key: value }.
Returns true if every object in the list matches the given properties.
Without properties, checks that all values are truthy.
Compute the <all-active: lowbar.every> from the <users> with { active: true }.
(* all-active = false *)
Compute the <all-truthy: lowbar.every> from [1, 2, 3].
(* all-truthy = true *)
some
Compute the <result: lowbar.some> from the <list> with { key: value }.
Returns true if any object in the list matches the given properties.
Compute the <has-admin: lowbar.some> from the <users> with { role: "admin" }.
(* has-admin = true *)
index-of
Compute the <result: lowbar.index-of> from the <list> with { value: x }.
Returns the position of the first occurrence of a value, or -1 if not found.
Compute the <pos: lowbar.index-of> from ["a", "b", "c", "b"] with { value: "b" }.
(* pos = 1 *)
last-index-of
Compute the <result: lowbar.last-index-of> from the <list> with { value: x }.
Returns the position of the last occurrence of a value, or -1.
Compute the <pos: lowbar.last-index-of> from ["a", "b", "c", "b"] with { value: "b" }.
(* pos = 3 *)
sorted-index
Compute the <result: lowbar.sorted-index> from the <sorted-list> with { value: x }.
Determines the index at which a value should be inserted into an already-sorted
list to maintain sort order.
Compute the <idx: lowbar.sorted-index> from [10, 20, 30, 40] with { value: 25 }.
(* idx = 2 *)
find-index
Compute the <result: lowbar.find-index> from the <list> with { key: value }.
Returns the index of the first object matching the given properties, or -1.
Compute the <idx: lowbar.find-index> from the <users> with { role: "admin" }.
(* idx = 0 *)
find-last-index
Compute the <result: lowbar.find-last-index> from the <list> with { key: value }.
Like find-index, but searches from the end, returning the last matching position.
Compute the <idx: lowbar.find-last-index> from the <users> with { role: "admin" }.
(* idx = 2 (Eve is the last admin) *)
Grouping & Sorting
Organize, rank, and restructure collections by field values. These qualifiers
take a field parameter to know which property to operate on.
sort-by
Compute the <result: lowbar.sort-by> from the <list> with { field: "..." }.
Returns a stably sorted copy of the list, ordered by the given field. Numeric fields
are compared numerically. Pass order: "desc" for descending order.
Compute the <by-age: lowbar.sort-by> from the <users> with { field: "age" }.
Compute the <names: lowbar.pluck> from the <by-age> with { field: "name" }.
(* names = ["Eve", "Bob", "Alice"] *)
Compute the <oldest-first: lowbar.sort-by> from the <users> with { field: "age", order: "desc" }.
(* Alice (30) first, then Bob (25), then Eve (22) *)
group-by
Compute the <result: lowbar.group-by> from the <list> with { field: "..." }.
Splits a list into groups based on a field value. Returns an object where each key
is a field value and each value is the list of matching items.
Compute the <by-role: lowbar.group-by> from the <users> with { field: "role" }.
(* by-role = { "admin": [{Alice}, {Eve}], "user": [{Bob}] } *)
count-by
Compute the <result: lowbar.count-by> from the <list> with { field: "..." }.
Like group-by, but returns the count per group instead of the items.
Compute the <counts: lowbar.count-by> from the <users> with { field: "role" }.
(* counts = { "admin": 2, "user": 1 } *)
index-by
Compute the <result: lowbar.index-by> from the <list> with { field: "..." }.
Creates a lookup object keyed by a unique field. Each value is the full object.
Ideal for building dictionaries from lists.
Compute the <lookup: lowbar.index-by> from the <users> with { field: "name" }.
(* lookup = { "Alice": {name: "Alice", ...}, "Bob": {name: "Bob", ...}, ... } *)
pluck
Compute the <result: lowbar.pluck> from the <list> with { field: "..." }.
Extracts a single property from every object in the list. A concise shorthand
for the most common projection operation.
Compute the <names: lowbar.pluck> from the <users> with { field: "name" }.
(* names = ["Alice", "Bob", "Eve"] *)
Compute the <ages: lowbar.pluck> from the <users> with { field: "age" }.
(* ages = [30, 25, 22] *)
partition
Compute the <result: lowbar.partition> from the <list> with { key: value }.
Splits a list into two: items that match the given properties, and items that don't.
Returns [matching, non-matching].
Compute the <split: lowbar.partition> from the <users> with { active: true }.
(* split = [[{Alice}, {Bob}], [{Eve}]] *)
max
Compute the <result: lowbar.max> from the <list>.
Returns the maximum value in a list. For objects, pass field to compare
by a specific property — the full object is returned, not just the field value.
Compute the <biggest: lowbar.max> from [5, 3, 8, 1].
(* biggest = 8 *)
Compute the <oldest: lowbar.max> from the <users> with { field: "age" }.
(* oldest = {name: "Alice", age: 30, ...} *)
min
Compute the <result: lowbar.min> from the <list>.
Returns the minimum value. Like max, accepts an optional field.
Compute the <youngest: lowbar.min> from the <users> with { field: "age" }.
(* youngest = {name: "Eve", age: 22, ...} *)
Set Operations
Combine and compare lists using set semantics. Pass the second list
via the with { } clause.
without
Compute the <result: lowbar.without> from the <list> with { values: [...] }.
Returns a copy of the list with all specified values removed.
Compute the <filtered: lowbar.without> from [1, 2, 3, 4, 5] with { values: [2, 4] }.
(* filtered = [1, 3, 5] *)
union
Compute the <result: lowbar.union> from the <list> with { other: [...] }.
Combines two lists, keeping only unique values. Items from both lists appear in the result,
but no duplicates.
Compute the <all: lowbar.union> from [1, 2, 3] with { other: [3, 4, 5] }.
(* all = [1, 2, 3, 4, 5] *)
intersection
Compute the <result: lowbar.intersection> from the <list> with { other: [...] }.
Returns only the values present in both lists.
Compute the <common: lowbar.intersection> from [1, 2, 3, 4] with { other: [3, 4, 5, 6] }.
(* common = [3, 4] *)
difference
Compute the <result: lowbar.difference> from the <list> with { other: [...] }.
Returns values that exist in the first list but not the second.
Compute the <only-mine: lowbar.difference> from [1, 2, 3, 4] with { other: [3, 4, 5] }.
(* only-mine = [1, 2] *)
Restructuring
Change the shape of your data — merge columns, split into pages, or convert
between lists and objects.
zip
Compute the <result: lowbar.zip> from the <list> with { other: [...] }.
Merges two lists by pairing elements at corresponding positions.
Produces a list of two-element arrays.
Compute the <pairs: lowbar.zip> from ["a", "b", "c"] with { other: [1, 2, 3] }.
(* pairs = [["a", 1], ["b", 2], ["c", 3]] *)
unzip
Compute the <result: lowbar.unzip> from the <list-of-pairs>.
The inverse of zip. Transposes a list of pairs into two separate lists.
Compute the <cols: lowbar.unzip> from [["a", 1], ["b", 2], ["c", 3]].
(* cols = [["a", "b", "c"], [1, 2, 3]] *)
object
Compute the <result: lowbar.object> from the <list-of-pairs>.
Converts a list of [key, value] pairs into an object. The reverse of pairs.
Compute the <obj: lowbar.object> from [["name", "Alice"], ["age", 30]].
(* obj = { name: "Alice", age: 30 } *)
chunk
Compute the <result: lowbar.chunk> from the <list> with { size: N }.
Splits a list into groups of the given size. The last chunk may be smaller if
the list doesn't divide evenly. Useful for pagination and batch processing.
Compute the <pages: lowbar.chunk> from [1, 2, 3, 4, 5, 6, 7] with { size: 3 }.
(* pages = [[1, 2, 3], [4, 5, 6], [7]] *)
Numeric
Aggregate numeric values in a list.
sum
Compute the <result: lowbar.sum> from the <list>.
Adds up all numeric values. Non-numeric values are ignored.
Compute the <total: lowbar.sum> from [10, 20, 30].
(* total = 60 *)
avg
Compute the <result: lowbar.avg> from the <list>.
Calculates the arithmetic mean of all numeric values.
Compute the <mean: lowbar.avg> from [10, 20, 30].
(* mean = 20.0 *)
reduce
Compute the <result: lowbar.reduce> from the <list> with { op: "..." }.
Folds a list down to a single value using a built-in operation.
Supports "+" (sum), "*" (product), and "join" (string concatenation).
For "join", pass an optional separator.
Compute the <total: lowbar.reduce> from [1, 2, 3, 4] with { op: "+" }.
(* total = 10 *)
Compute the <product: lowbar.reduce> from [1, 2, 3, 4, 5] with { op: "*" }.
(* product = 120 *)
Compute the <sentence: lowbar.reduce> from ["hello", "world"] with { op: "join", separator: " " }.
(* sentence = "hello world" *)
Objects
Inspect, reshape, and merge objects. These qualifiers work on key-value structures.
keys
Compute the <result: lowbar.keys> from the <object>.
Returns all keys of an object as a sorted list.
Compute the <k: lowbar.keys> from { host: "localhost", port: 8080 }.
(* k = ["host", "port"] *)
values
Compute the <result: lowbar.values> from the <object>.
Returns all values of an object as a list.
Compute the <v: lowbar.values> from { host: "localhost", port: 8080 }.
(* v = ["localhost", 8080] *)
pairs
Compute the <result: lowbar.pairs> from the <object>.
Converts an object into a list of [key, value] pairs. The inverse of object.
Compute the <entries: lowbar.pairs> from { a: 1, b: 2 }.
(* entries = [["a", 1], ["b", 2]] *)
invert
Compute the <result: lowbar.invert> from the <object>.
Swaps keys and values. Values become keys, keys become values.
Create the <colors> with { red: "#ff0000", green: "#00ff00" }.
Compute the <lookup: lowbar.invert> from the <colors>.
(* lookup = { "#ff0000": "red", "#00ff00": "green" } *)
pick
Compute the <result: lowbar.pick> from the <object> with { keys: [...] }.
Returns a copy of the object containing only the listed keys. The allow-list approach
to object filtering.
Create the <user> with { name: "Alice", email: "a@b.com", password: "secret" }.
Compute the <public: lowbar.pick> from the <user> with { keys: ["name", "email"] }.
(* public = { name: "Alice", email: "a@b.com" } *)
omit
Compute the <result: lowbar.omit> from the <object> with { keys: [...] }.
Returns a copy without the listed keys. The deny-list counterpart to pick.
Compute the <safe: lowbar.omit> from the <user> with { keys: ["password"] }.
(* safe = { name: "Alice", email: "a@b.com" } *)
defaults
Compute the <result: lowbar.defaults> from the <object> with { key: value, ... }.
Fills in missing properties with default values. Existing properties are never overwritten.
The safe way to ensure an object has all required fields.
Create the <config> with { host: "localhost" }.
Compute the <full: lowbar.defaults> from the <config> with { host: "0.0.0.0", port: 8080, debug: false }.
(* full = { host: "localhost", port: 8080, debug: false } *)
(* Note: host kept its original value *)
extend
Compute the <result: lowbar.extend> from the <object> with { key: value, ... }.
Merges the with properties into the object, overwriting any existing keys.
The forceful cousin of defaults.
Compute the <updated: lowbar.extend> from the <config> with { port: 9090, debug: true }.
(* updated = { host: "localhost", port: 9090, debug: true } *)
clone
Compute the <result: lowbar.clone> from the <value>.
Creates a shallow copy of an object or list.
Compute the <copy: lowbar.clone> from the <config>.
(* copy = { host: "localhost" } (independent copy) *)
has
Compute the <result: lowbar.has> from the <object> with { key: "..." }.
Checks whether an object contains a specific key. Returns a boolean.
Compute the <exists: lowbar.has> from { name: "Alice" } with { key: "name" }.
(* exists = true *)
get
Compute the <result: lowbar.get> from the <object> with { path: "..." }.
Retrieves a value at a nested dot-separated path. Supports an optional default
value when the path doesn't resolve.
Create the <data> with { user: { address: { city: "Portland" } } }.
Compute the <city: lowbar.get> from the <data> with { path: "user.address.city" }.
(* city = "Portland" *)
Compute the <phone: lowbar.get> from the <data> with { path: "user.phone", default: "N/A" }.
(* phone = "N/A" *)
find-key
Compute the <result: lowbar.find-key> from the <object> with { value: x }.
Returns the first key whose value matches. The reverse lookup.
Create the <codes> with { red: "#ff0000", green: "#00ff00" }.
Compute the <name: lowbar.find-key> from the <codes> with { value: "#ff0000" }.
(* name = "red" *)
map-object
Compute the <result: lowbar.map-object> from the <object> with { from: "...", to: "..." }.
Renames keys in an object. Use from/to for a single rename,
or map for bulk renaming.
Compute the <renamed: lowbar.map-object> from { first_name: "Alice" } with { from: "first_name", to: "name" }.
(* renamed = { name: "Alice" } *)
Compute the <mapped: lowbar.map-object> from { a: 1, b: 2 } with { map: { a: "x", b: "y" } }.
(* mapped = { x: 1, y: 2 } *)
is-match
Compute the <result: lowbar.is-match> from the <object> with { key: value, ... }.
Returns true if the object contains all the given key-value pairs.
A subset check for objects.
Compute the <match: lowbar.is-match> from { name: "Alice", role: "admin" } with { role: "admin" }.
(* match = true *)
Type Checks
Inspect the type of any value. Each returns a boolean.
is-empty
Compute the <result: lowbar.is-empty> from the <value>.
Returns true for empty lists, empty strings, empty objects, and nil.
Everything else is considered non-empty.
Compute the <a: lowbar.is-empty> from [].
(* a = true *)
Compute the <b: lowbar.is-empty> from "hello".
(* b = false *)
is-array
Compute the <result: lowbar.is-array> from the <value>.
Returns true if the value is a list.
Compute the <check: lowbar.is-array> from [1, 2].
(* check = true *)
is-string
Compute the <result: lowbar.is-string> from the <value>.
Returns true if the value is a string.
Compute the <check: lowbar.is-string> from "hello".
(* check = true *)
is-number
Compute the <result: lowbar.is-number> from the <value>.
Returns true if the value is an integer or floating-point number.
Compute the <check: lowbar.is-number> from 42.
(* check = true *)
is-boolean
Compute the <result: lowbar.is-boolean> from the <value>.
Returns true if the value is a boolean.
Compute the <check: lowbar.is-boolean> from true.
(* check = true *)
is-object
Compute the <result: lowbar.is-object> from the <value>.
Returns true if the value is an object (key-value dictionary).
Compute the <check: lowbar.is-object> from { a: 1 }.
(* check = true *)
is-null
Compute the <result: lowbar.is-null> from the <value>.
Returns true if the value is nil/null.
is-finite
Compute the <result: lowbar.is-finite> from the <number>.
Returns true if the value is a finite number (not infinity or NaN).
Compute the <check: lowbar.is-finite> from 42.
(* check = true *)
is-equal
Compute the <result: lowbar.is-equal> from the <value> with { other: x }.
Deep equality comparison between two values.
Compute the <same: lowbar.is-equal> from 42 with { other: 42 }.
(* same = true *)
Compute the <diff: lowbar.is-equal> from "hello" with { other: "world" }.
(* diff = false *)
Utilities
String manipulation, data conversion, and pipeline helpers.
identity
Compute the <result: lowbar.identity> from the <value>.
Returns the value unchanged. Sounds useless, but it's the default
qualifier — a no-op that's occasionally exactly what you need in a pipeline.
Compute the <same: lowbar.identity> from 42.
(* same = 42 *)
escape
Compute the <result: lowbar.escape> from the <string>.
Escapes a string for safe HTML insertion, converting &, <,
>, ", and ' to their HTML entity equivalents.
Compute the <safe: lowbar.escape> from "<b>bold & \"italic\"</b>".
(* safe = "<b>bold & "italic"</b>" *)
unescape
Compute the <result: lowbar.unescape> from the <string>.
The inverse of escape. Converts HTML entities back to their characters.
Compute the <raw: lowbar.unescape> from "<b>bold</b>".
(* raw = "<b>bold</b>" *)
join
Compute the <result: lowbar.join> from the <list> with { separator: "..." }.
Concatenates all elements into a single string with a separator between each.
Defaults to ",".
Compute the <csv: lowbar.join> from ["alice", "bob", "eve"] with { separator: ", " }.
(* csv = "alice, bob, eve" *)
split
Compute the <result: lowbar.split> from the <string> with { separator: "..." }.
Splits a string into a list by a separator. The inverse of join.
Compute the <parts: lowbar.split> from "one:two:three" with { separator: ":" }.
(* parts = ["one", "two", "three"] *)
tap
Compute the <result: lowbar.tap> from the <value>.
Returns the value unchanged — a pass-through useful as a checkpoint in
data pipelines or debugging.
Compute the <debug: lowbar.tap> from the <data>.
Log <debug> to the <console>.
(* Logs the data and passes it through *)
Actions
Actions generate new data rather than transforming existing values.
They use the Lowbar. prefix (PascalCase) as verb-based statements.
Range
Lowbar.Range the <result> with { stop: N }.
Generates a list of integers from start (default 0) up to
but not including stop, incrementing by step (default 1).
Automatically counts down when start is greater than stop.
Lowbar.Range the <digits> with { stop: 5 }.
(* digits = [0, 1, 2, 3, 4] *)
Lowbar.Range the <evens> with { start: 0, stop: 10, step: 2 }.
(* evens = [0, 2, 4, 6, 8] *)
Lowbar.Range the <countdown> with { start: 5, stop: 0 }.
(* countdown = [5, 4, 3, 2, 1] *)
Random
Lowbar.Random the <result> with { min: N, max: N }.
Generates a random integer between min and max inclusive.
Defaults to 0–100.
Lowbar.Random the <dice> with { min: 1, max: 6 }.
(* dice = 4 (random 1-6) *)
Lowbar.Random the <percent> with { min: 0, max: 100 }.
(* percent = 73 (random 0-100) *)
UniqueId
Lowbar.UniqueId the <result> with { prefix: "..." }.
Generates a globally unique identifier with an optional prefix.
Each call produces a new, incrementing ID.
Lowbar.UniqueId the <id1> with { prefix: "user_" }.
Lowbar.UniqueId the <id2> with { prefix: "user_" }.
(* id1 = "user_1" *)
(* id2 = "user_2" *)
Now
Lowbar.Now the <result> for the <system>.
Returns the current Unix timestamp in milliseconds. Useful for timing
and date calculations.
Lowbar.Now the <timestamp> for the <system>.
(* timestamp = 1713436800000 *)
Times
Lowbar.Times the <result> with { n: N, value: x }.
Creates a list containing n copies of a value.
Lowbar.Times the <stars> with { n: 5, value: "*" }.
(* stars = ["*", "*", "*", "*", "*"] *)
Lowbar.Times the <zeros> with { n: 3, value: 0 }.
(* zeros = [0, 0, 0] *)