Skip to content

Methods

MethodReturnsDescription
.length()CountstoneNumber of characters
.upper()RunestoneUppercase copy
.lower()RunestoneLowercase copy
.trim()RunestoneWhitespace stripped from both ends
.contains(sub)FlagstoneWhether string contains substring
.starts_with(prefix)FlagstoneWhether string starts with prefix
.ends_with(suffix)FlagstoneWhether string ends with suffix
.replace(old, new)RunestoneReplace all occurrences
.split(sep)ScrollSplit into array by separator
.chars()ScrollSplit into array of single characters
.indexOf(sub)CountstoneIndex of first occurrence (-1 if not found)
.repeat(n)RunestoneRepeat string n times
.slice(start, end)RunestoneExtract substring
Runestone msg is " Hello, World! ";
Chant(msg.trim()); // "Hello, World!"
Chant(msg.trim().upper()); // "HELLO, WORLD!"
Chant(msg.trim().lower()); // "hello, world!"
Chant(msg.contains("World")); // Truth
Chant(msg.trim().starts_with("He")); // Truth
Chant(msg.trim().replace("World", "RuneLang")); // "Hello, RuneLang!"
Scroll words is "one,two,three".split(",");
Chant(words); // ["one", "two", "three"]
Scroll chars is "abc".chars();
Chant(chars); // ["a", "b", "c"]
Chant("ha".repeat(3)); // "hahaha"
Chant("hello".indexOf("llo")); // 2

Strings support slice syntax [start:end]:

Runestone word is "RuneLang";
Chant(word[0:4]); // "Rune"
Chant(word[4:]); // "Lang"
Chant(word[:4]); // "Rune"
Chant("=" * 40); // "========================================"
Chant("na" * 8); // "nananananananana"

These modify the array in-place (requires Mutable):

MethodReturnsDescription
.push(val)VoidAppend element to end
.pop()ValueRemove and return last element
MethodReturnsDescription
.length()CountstoneNumber of elements
.contains(val)FlagstoneWhether array contains value
.indexOf(val)CountstoneIndex of first occurrence (-1 if not found)

These take a function (Spell/lambda) as an argument and return new values:

MethodReturnsDescription
.map(fn)ScrollTransform each element
.filter(fn)ScrollKeep elements where fn returns truthy
.reduce(init, fn)ValueAccumulate with fn(accumulator, element)
.forEach(fn)VoidExecute fn on each element (side effects)
.find(fn)ValueFirst element where fn returns truthy
MethodReturnsDescription
.sort()ScrollNew sorted array (ascending)
.reverse()ScrollNew reversed array
.flat()ScrollFlatten one level of nesting
.join(sep)RunestoneJoin elements into string with separator
.slice(start, end)ScrollExtract sub-array
Scroll nums is [5, 3, 8, 1, 9, 2, 7, 4, 6];
// higher-order methods
Scroll doubled is nums.map((Countstone n) => n * 2);
Chant(doubled); // [10, 6, 16, 2, 18, 4, 14, 8, 12]
Scroll big is nums.filter((Countstone n) => n > 5);
Chant(big); // [8, 9, 7, 6]
Countstone sum is nums.reduce(0, (Countstone acc, Countstone n) => acc + n);
Chant(sum); // 45
Countstone first_big is nums.find((Countstone n) => n > 7);
Chant(first_big); // 8
// transform methods
Chant(nums.sort()); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
Chant(nums.reverse()); // [6, 4, 7, 2, 9, 1, 8, 3, 5]
Chant(nums.indexOf(8)); // 2
// join
Chant(["a", "b", "c"].join(" -> ")); // "a -> b -> c"
// flat
Scroll nested is [[1, 2], [3, 4], [5]];
Chant(nested.flat()); // [1, 2, 3, 4, 5]
// slice
Chant(nums.slice(2, 5)); // [8, 1, 9]

Arrays support slice syntax [start:end]:

Scroll items is [10, 20, 30, 40, 50];
Chant(items[1:3]); // [20, 30]
Chant(items[:2]); // [10, 20]
Chant(items[3:]); // [40, 50]
MethodReturnsDescription
.keys()ScrollArray of all keys
.values()ScrollArray of all values
.entries()ScrollArray of [key, value] pairs
.has(key)FlagstoneWhether key exists
.length()CountstoneNumber of entries
.remove(key)ValueRemove key and return its value
.merge(other)TomeReturn new Tome with entries from both
Tome hero is {"name": "Thorin", "class": "Warrior", "level": 15};
Chant(hero.keys()); // ["name", "class", "level"]
Chant(hero.values()); // ["Thorin", "Warrior", 15]
Chant(hero.entries()); // [["name", "Thorin"], ["class", "Warrior"], ["level", 15]]
Chant(hero.has("name")); // Truth
Chant(hero.has("mana")); // Falsehood
Chant(hero.length()); // 3
// merge creates a new tome
Tome extra is {"weapon": "Axe", "level": 20};
Tome merged is hero.merge(extra);
Chant(merged);
// {"name": "Thorin", "class": "Warrior", "level": 20, "weapon": "Axe"}
// note: "level" was overwritten by the second tome's value