Builtins¶
In Kiwi, builtins are accessed using dot-notation and can be used to query or manipulate values and types.
global¶
The global variable is a hashmap that can be used to store global data. This is useful for sharing data between scripts.
Date Builtins¶
year()¶
Returns the year part.
month()¶
Returns the month part. (1 through 12)
day()¶
Returns the day part. (1 through number of days in the month)
hour()¶
Returns the hour part. (0 through 23)
minute()¶
Returns the minute part. (0 through 59)
second()¶
Returns the second part. (0 through 59)
millisecond()¶
Returns the millisecond part. (0 through 999)
String Builtins¶
begins_with(str)¶
Returns true if the string begins with a given string.
println("foobar".begins_with("foo")) # prints: true
println("foobar".begins_with("food")) # prints: false
chars()¶
Converts a string into a list. Each character in the string becomes a new string in the list.
string = "Hello"
chars = string.chars()
# chars = ["H", "e", "l", "l", "o"]
println("kiwi".chars()) # prints: ["k", "i", "w", "i"]
chomp()¶
Strips a trailing newline (\r\n, \n, or \r) from the string. Returns the string unchanged if it does not end with a newline.
line = "Hello, World!\n"
println line.chomp() # prints: Hello, World!
line2 = "No newline"
println line2.chomp() # prints: No newline
contains(str)¶
Returns true if the string contains a given string.
ends_with(str)¶
Returns true if the string ends with a given string.
println("foobar".ends_with("bar")) # prints: true
println("foobar".ends_with("bark")) # prints: false
hex_bytes()¶
Parses a hex-encoded string into a bytes value. The string may contain spaces and tabs (which are stripped). The hex string must have an even number of characters after whitespace is removed.
data = "48 65 6C 6C 6F".hex_bytes()
println data.size() # prints: 5
println data # prints the raw byte array
index(str)¶
Returns the index of a string. Returns -1 if not found.
lastindex(str)¶
Returns the last index of a string. Returns -1 if not found.
lines()¶
Splits the string into a list of lines, splitting on the platform newline sequence.
text = "line one\nline two\nline three"
println text.lines() # prints: ["line one", "line two", "line three"]
lowercase()¶
Returns the lowercase value of a string.
ltrim()¶
Trims whitespace from the left-hand side of a string.
ord()¶
Returns the Unicode code point (as an integer) of the first character of the string. Throws an error if the string is empty.
println("A".ord()) # prints: 65
println("kiwi".ord()) # prints: 107
println("🥝".ord()) # prints: 129373
rtrim()¶
Trims whitespace from the right-hand side of a string.
trim()¶
Trims whitespace from both sides of a string.
uppercase()¶
Returns the uppercase value of a string.
substring(pos, length)¶
Extract a substring from a string.
Regex Builtins¶
find(regex)¶
Searches for the first occurrence of a pattern described by a regex and returns the substring.
println("my email: example@test.com".find('\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z0-9]{2,}\b'))
# prints: example@test.com
match(regex)¶
Returns the capture groups for the first match of the regex in the string.
matches(regex)¶
Tests whether the entire string conforms to a regular expression pattern.
println("hello123".matches('^([a-z]+\d{3})$')) # prints: true
println("hello123!".matches('^([a-z]+\d{3})$')) # prints: false
matches_all(regex)¶
Checks if all parts of the string conform to the regex pattern.
println("123-456-7890".matches_all('\d{3}-\d{3}-\d{4}')) # prints: true
println("123-456-789x".matches_all('\d{3}-\d{3}-\d{4}')) # prints: false
replace(search, replacement)¶
Search for a string (or regex pattern) and replace with a given string. Supports regex capture group back-references.
println("foobar".replace("foo", "food")) # prints: foodbar
println("foo123bar".replace('(\d+)', '[$1]')) # prints: foo[123]bar
println("foo123bar456".replace('\d+', "-")) # prints: foo-bar-
rreplace(pattern, replacement)¶
Like replace, but replaces only the last occurrence of the pattern.
println("aabbcc".rreplace("b", "X")) # prints: aabXcc
println("foo-bar-baz".rreplace('-\w+', "!")) # prints: foo-bar!
rsplit(delimiter, limit = -1)¶
Splits a string by delimiter, working from right to left. The optional limit caps the number of splits. Useful for peeling off a suffix or file extension.
println("a.b.c.d".rsplit(".", 1)) # prints: ["a.b.c", "d"]
println("a.b.c.d".rsplit(".")) # prints: ["a", "b", "c", "d"]
scan(regex)¶
Finds every occurrence of the regex in the string and returns a list of matches.
split(delim, limit = -1)¶
Splits a string into a list by delimiter.
println("Hello World!".split(" ")) # prints: ["Hello", "World!"]
println("one,two,three,four".split(",", 2)) # prints: ["one", "two,three,four"]
Range Checking¶
between(a, b)¶
Returns true if the value falls within the inclusive range [a, b]. Works on numbers, strings (lexicographic order), and dates.
# Numbers
println (5).between(1, 10) # prints: true
println (15).between(1, 10) # prints: false
# Floats
println (3.14).between(3.0, 4.0) # prints: true
# Strings (lexicographic order)
println "kiwi".between("apple", "mango") # prints: true
println "zebra".between("apple", "mango") # prints: false
# Dates
start = "2024-01-01".to_date()
end = "2024-12-31".to_date()
today = "2024-06-15".to_date()
println today.between(start, end) # prints: true
Hashmap Builtins¶
keys()¶
Returns the list of keys from a hashmap.
hashmap = {
"key1": true,
"key2": 1,
"key3": ["a", "b", "c"]
}
println(hashmap.keys()) # prints: ["key1", "key2", "key3"]
has_key(key)¶
Returns true if a hashmap contains a given key.
hashmap = { "key1": true, "key2": 1 }
println(hashmap.has_key("key2")) # prints: true
println(hashmap.has_key("key9")) # prints: false
get(key, default = null)¶
Returns the value assigned to a given key. If the key is not present and a default is supplied, returns the default instead of null.
hashmap = { "a": 1, "b": 2 }
println(hashmap.get("a")) # prints: 1
println(hashmap.get("z", 99)) # prints: 99
println(hashmap.get("z")) # prints: null
set(key, value)¶
Sets the value assigned to a given key (creates the key if it does not exist).
hashmap = { "key1": true }
hashmap.set("key1", false)
hashmap.set("key2", 42)
println hashmap # prints: {"key1": false, "key2": 42}
merge(hashmap)¶
Merge a hashmap with another. Keys in the argument override matching keys in the receiver.
hashmap1 = {"a": 1, "b": 2}
hashmap2 = {"b": 3, "c": 4}
println(hashmap1.merge(hashmap2)) # prints: {"a": 1, "b": 3, "c": 4}
remove(key)¶
Removes a key-value pair from the hashmap. Returns the hashmap after removal.
values()¶
Returns the list of values from a hashmap.
hashmap = { "key1": true, "key2": 1, "key3": ["a", "b", "c"] }
println(hashmap.values()) # prints: [true, 1, ["a", "b", "c"]]
List Builtins¶
all(lambda)¶
Returns true if all elements in a list match a given condition.
list = [2, 4, 6]
println list.all(do (n) => n % 2 == 0) # prints: true
list.push(5)
println list.all(do (n) => n % 2 == 0) # prints: false
append(value)¶
Alias for push. Adds a value to the end of a list.
clear()¶
Clears a list or a hashmap.
concat(list)¶
Combine two lists into one.
count(value)¶
Count occurrences of a specific value in the list.
dequeue()¶
Removes and returns a value from the beginning of a list.
each(lambda)¶
Iterate a list, performing some action for each item in the list.
# Convert "hello" to a list of unique values, and iterate each.
"hello".chars().unique().each(do (v, i) => println "${i} = ${v}")
/# Prints:
0 = h
1 = e
2 = l
3 = o
#/
# Iterate a range.
[1 to 5].each(do (v, i) => println "${i}: ${v}")
/# Prints:
0: 1
1: 2
2: 3
3: 4
4: 5
#/
enqueue(value)¶
Pushes a value onto the end of a list (alias for push).
filter(lambda)¶
Filter a list based on a condition.
words = ["kiwi", "mango", "strawberry"]
println words.filter(do (w) => w.size() > 4)
# prints: ["mango", "strawberry"]
first(default = null)¶
Returns the first value in a list. Returns null (or a provided default) if the list is empty.
flatten()¶
Flatten nested lists into a single list.
index(value)¶
Returns the index of an item in a list. Returns -1 if not found.
insert(index, value)¶
Insert a value at a specified index.
join(str)¶
Joins a list into a string with an optional separator.
println(["Hello", "World!"].join(" ")) # prints: Hello World!
println([1, 2, 3].join(", ")) # prints: 1, 2, 3
last(default = null)¶
Returns the last value in a list. Returns null (or a provided default) if the list is empty.
lastindex(value)¶
Returns the last index of an item in a list. Returns -1 if not found.
println([1, 0, 0, 1, 0, 1, 1].lastindex(1)) # prints: 6
println([1, 2, 3, 4, 5].lastindex(6)) # prints: -1
map(lambda)¶
Transform each element in a list, returning a new list.
list = ["kiwi", "mango", "banana"]
println list.map(do (item) => item.uppercase())
# prints: ["KIWI", "MANGO", "BANANA"]
max()¶
Get the highest value in a list.
min()¶
Get the lowest value in a list.
none(lambda)¶
Returns true if no elements in the list satisfy the predicate. The inverse of all.
list = [1, 3, 5, 7]
println list.none(do (n) => n % 2 == 0) # prints: true (no even numbers)
list.push(4)
println list.none(do (n) => n % 2 == 0) # prints: false (4 is even)
pop()¶
Returns and removes a value from the end of a list.
push(value)¶
Pushes a value onto the end of a list.
reduce(accumulator, lambda)¶
Aggregate the items in a list into a single value.
numbers = [1, 2, 3, 4, 5]
result = numbers.reduce({}, do (acc, n)
acc["key${n}"] = n
acc
end)
println result # prints: {"key1": 1, "key2": 2, "key3": 3, "key4": 4, "key5": 5}
remove(value)¶
Remove the first occurrence of a specific value in a list.
println([1, 2, 3].remove(2)) # prints: [1, 3]
println(["a", "b", 3, 4].remove("b")) # prints: ["a", 3, 4]
remove_at(index)¶
Remove a value from a list at a specified index.
reverse()¶
Reverse a list or a string.
rotate(n)¶
Rotate the values of the list by a specified number of positions.
If n is positive, values rotate right. If n is negative, values rotate left.
println "abcd".chars().rotate(1) # prints: ["d", "a", "b", "c"]
println "abcd".chars().rotate(0) # prints: ["a", "b", "c", "d"]
println "abcd".chars().rotate(-1) # prints: ["b", "c", "d", "a"]
shift()¶
Removes and returns the first value of a list.
size()¶
Returns the size of a list, string, hashmap, or byte array as an integer.
println("four".size()) # prints: 4
println([1, 2, 3, true].size()) # prints: 4
println({a: 1, b: 2}.size()) # prints: 2
skip(n)¶
Returns a new list with the first n elements removed.
slice(start, end)¶
Get a subset of the list, specifying start (inclusive) and end (exclusive) indices.
println([1, 2, 3].slice(1, 2)) # prints: [2]
println([1, 2, 3].slice(0, 3)) # prints: [1, 2, 3]
println([1, 2, 3].slice(0, 2)) # prints: [1, 2]
sort()¶
Sort a list in ascending order.
list = ["kiwi", "mango", "guava"]
println(list.sort()) # prints: ["guava", "kiwi", "mango"]
println([3, 1, 2].sort()) # prints: [1, 2, 3]
sort(lambda)¶
Sort a list using a custom comparator. The lambda receives two elements and should return true if the first argument should come before the second.
# Sort descending
nums = [3, 1, 4, 1, 5, 9, 2, 6]
println nums.sort(do (a, b) => a > b) # prints: [9, 6, 5, 4, 3, 2, 1, 1]
# Sort strings by length
words = ["banana", "fig", "kiwi", "mango"]
println words.sort(do (a, b) => a.size() < b.size())
# prints: ["fig", "kiwi", "mango", "banana"]
sum()¶
Sum the numeric values in a list. Returns an integer if all values are integers, otherwise a float.
swap(index1, index2)¶
Swaps two values in a list by index.
take(n)¶
Returns a new list containing only the first n elements.
to_bytes()¶
Converts a string or list value to a byte array.
println("kiwi".to_bytes()) # byte array of UTF-8 encoded string
println("kiwi".chars().to_bytes()) # same result via chars
to_hex()¶
Converts a byte array or list of integer byte values to a lowercase hexadecimal string.
println([97, 115, 116, 114, 97, 108].to_hex()) # prints: 61737472616c
println("kiwi".chars().to_bytes().to_hex())
unique()¶
Remove duplicate values from the list.
println("aaaabbcccc".chars().unique()) # prints: ["a", "b", "c"]
println([1, 2, 2, 3, 3, 3].unique()) # prints: [1, 2, 3]
unshift(value)¶
Inserts a value at the beginning of a list.
zip(list)¶
Combine values from two lists into pairs.
println([1, 2].zip([3, 4])) # prints: [[1, 3], [2, 4]]
println([1, 2, 3].zip(["a", "b", "c"])) # prints: [[1, "a"], [2, "b"], [3, "c"]]
Conversion and Type Checking¶
between(a, b)¶
clone()¶
Returns a deep copy of the value.
list = [1, 2, 3, true, false]
list2 = list.clone()
list2[0] = "hello"
println(list) # prints: [1, 2, 3, true, false]
println(list2) # prints: ["hello", 2, 3, true, false]
empty(default = null)¶
Returns true if the value is a "default" (zero-like) value: empty string, empty list, empty hashmap, 0, 0.0, false, or null.
If a default argument is provided, returns that value when empty instead of true.
println((0).empty()) # prints: true
println("".empty()) # prints: true
println([].empty()) # prints: true
println({}.empty()) # prints: true
println(false.empty()) # prints: true
println("hi".empty()) # prints: false
# With a default value:
name = ""
println name.empty("anonymous") # prints: anonymous
score = 100
println score.empty(0) # prints: 100 (not empty, returns value itself)
is_a(type_name)¶
Used for type-checking. Accepts a type name string or a struct reference. For struct instances, also checks the full inheritance hierarchy.
println("foobar".is_a(string)) # prints: true
println(42.is_a(integer)) # prints: true
println([].is_a(list)) # prints: true
struct Animal end
struct Dog < Animal end
d = Dog.new()
println d.is_a(Dog) # prints: true
println d.is_a(Animal) # prints: true (checks hierarchy)
pretty()¶
Returns a pretty-printed (indented) serialization of the value.
hashmap = {
"key1": true,
"key2": 1,
"key3": ["a", "b", "c"]
}
println(hashmap.pretty())
/# prints:
{
"key1": true,
"key2": 1,
"key3": [
"a",
"b",
"c"
]
}
#/
to_date(format = null)¶
Converts a string or integer to a date value.
- String with no format: parsed with
DateTime.TryParse(ISO 8601 and common locale formats). - String with format: parsed using the exact format string (e.g.
"dd/MM/yyyy"). - Integer: treated as a Unix timestamp in milliseconds.
Returns a default (zero) date if parsing fails.
d1 = "2024-06-15".to_date()
println d1.year() # prints: 2024
println d1.month() # prints: 6
println d1.day() # prints: 15
# Custom format
d2 = "15/06/2024".to_date("dd/MM/yyyy")
println d2.year() # prints: 2024
# From Unix timestamp (ms)
d3 = 1718409600000.to_date()
println d3.year() # prints: 2024
to_float()¶
Converts a numeric or string value to a float.
to_integer()¶
Converts a numeric or string value to an integer (truncates floats).
to_list()¶
Converts a string to a list of characters, or a byte array to a list of integer byte values.
println("abc".to_list()) # prints: ["a", "b", "c"]
println("kiwi".to_bytes().to_list()) # prints: [107, 105, 119, 105]
to_string(format = null)¶
Converts a value to a string.
Formatting Options¶
For integer and float values, an optional format specifier can be passed.
| Format | Name | Description | Example |
|---|---|---|---|
"B" / "b" |
Binary | 16-digit binary, zero-padded | (31337).to_string("b") -> 0111101001101001 |
"Fn" / "fn" |
Fixed-Point | n decimal places |
(100).to_string("f2") -> 100.00 |
"O" / "o" |
Octal | Octal representation | (64).to_string("o") -> 100 |
"X" |
Hexadecimal (upper) | Uppercase hex | (43).to_string("X") -> 2B |
"x" |
Hexadecimal (lower) | Lowercase hex | (43).to_string("x") -> 2b |
truthy()¶
Returns the truthiness of a value.
println null.truthy() # prints: false — null is never truthy
println (0).truthy() # prints: false — 0 is the only non-truthy integer
println (1).truthy() # prints: true
println "".truthy() # prints: false
println "0".truthy() # prints: true — non-empty strings are truthy
println [].truthy() # prints: false
println [0].truthy() # prints: true — non-empty lists are truthy
println {}.truthy() # prints: false — empty hashmaps are not truthy
println true.truthy() # prints: true
type()¶
Returns the type of the value as a string.
Valid types: integer, float, boolean, string, list, hashmap, lambda, date, bytes, none. For struct instances, returns the struct name.
struct MyStruct end
instance = MyStruct.new()
println(instance.type()) # prints: MyStruct
println("Kiwis are delicious!".type()) # prints: string
println(42.type()) # prints: integer
println(3.14.type()) # prints: float
deserialize(str)¶
Deserializes a JSON-like string into a Kiwi value.
serialize(value)¶
Serializes a Kiwi value into its string representation.