% API
Builtins
USE_COLOR
USE_COLOR : Bool
Whether or not the console prefers ANSI color escape sequences in the output.
ask
ask : func(prompt: Text, bold: Bool = yes, force_tty: Bool = yes -> Text?)
Gets a line of user input text with a prompt.
When a program is receiving input from a pipe or writing its output to a pipe, this flag (which is enabled by default) forces the program to write the prompt to /dev/tty and read the input from /dev/tty, which circumvents the pipe. This means that foo | ./tomo your-program | baz will still show a visible prompt and read user input, despite the pipes. Setting this flag to no will mean that the prompt is written to stdout and input is read from stdin, even if those are pipes.
| Argument | Type | Description | Default |
|---|---|---|---|
| prompt | Text |
The text to print as a prompt before getting the input. | - |
| bold | Bool |
Whether or not to print make the prompt appear bold on a console. | yes |
| force_tty | Bool |
Whether or not to force the use of /dev/tty. | yes |
Return: A line of user input text without a trailing newline, or empty text if something went wrong (e.g. the user hit Ctrl-D).
Example:
assert ask("What's your name? ") == "Arthur Dent"
at_cleanup
at_cleanup : func(fn: func() -> Void)
Register a function that runs at cleanup time for Tomo programs. Cleanup time happens when a program exits (see atexit() in C), or immediately before printing error messages in a call to fail(). This allows for terminal cleanup so error messages can be visible as the program shuts down.
Use this API very carefully, because errors that occur during cleanup functions may make it extremely hard to figure out what's going on. Cleanup functions should be designed to not error under any circumstances.
| Argument | Type | Description | Default |
|---|---|---|---|
| fn | func() |
A function to run at cleanup time. | - |
Return: Nothing.
Example:
at_cleanup(func()
_ := (/tmp/file.txt).remove(ignore_missing=yes)
)
exit
exit : func(message: Text? = none, status: Int32 = Int32(1) -> Abort)
Exits the program with a given status and optionally prints a message.
| Argument | Type | Description | Default |
|---|---|---|---|
| message | Text? |
If nonempty, this message will be printed (with a newline) before exiting. | none |
| status | Int32 |
The status code that the program with exit with. | Int32(1) |
Return: This function never returns.
Example:
exit("Goodbye forever!", Int32(1))
fail
fail : func(message: Text -> Abort)
Prints a message to the console, aborts the program, and prints a stack trace.
| Argument | Type | Description | Default |
|---|---|---|---|
| message | Text |
The error message to print. | - |
Return: Nothing, aborts the program.
Example:
fail("Oh no!")
getenv
getenv : func(name: Text -> Text?)
Gets an environment variable.
| Argument | Type | Description | Default |
|---|---|---|---|
| name | Text |
The name of the environment variable to get. | - |
Return: If set, the environment variable's value, otherwise, none.
Example:
assert getenv("TERM") == "xterm-256color"
assert getenv("not_a_variable") == none
print : func(text: Text, newline: Bool = yes -> Void)
Prints a message to the console (alias for say()).
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to print. | - |
| newline | Bool |
Whether or not to print a newline after the text. | yes |
Return: Nothing.
Example:
print("Hello ", newline=no)
print("world!")
say
say : func(text: Text, newline: Bool = yes -> Void)
Prints a message to the console.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to print. | - |
| newline | Bool |
Whether or not to print a newline after the text. | yes |
Return: Nothing.
Example:
say("Hello ", newline=no)
say("world!")
setenv
setenv : func(name: Text, value: Text? -> Void)
Sets an environment variable.
| Argument | Type | Description | Default |
|---|---|---|---|
| name | Text |
The name of the environment variable to set. | - |
| value | Text? |
The new value of the environment variable. If none, then the environment variable will be unset. |
- |
Return: Nothing.
Example:
setenv("FOOBAR", "xyz")
sleep
sleep : func(seconds: Num -> Void)
Pause execution for a given number of seconds.
| Argument | Type | Description | Default |
|---|---|---|---|
| seconds | Num |
How many seconds to sleep for. | - |
Return: Nothing.
Example:
sleep(1.5)
Bool
Bool.parse
Bool.parse : func(text: Text, remainder: &Text? = none -> Bool?)
Converts a text representation of a boolean value into a boolean. Acceptable boolean values are case-insensitive variations of yes/no, y/n, true/false, on/off.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The string containing the boolean value. | - |
| remainder | &Text? |
If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | none |
Return: yes if the string matches a recognized truthy boolean value; otherwise return no.
Example:
assert Bool.parse("yes") == yes
assert Bool.parse("no") == no
assert Bool.parse("???") == none
assert Bool.parse("yesJUNK") == none
remainder : Text
assert Bool.parse("yesJUNK", &remainder) == yes
assert remainder == "JUNK"
Byte
Byte.get_bit
Byte.get_bit : func(i: Byte, bit_index: Int -> Bool)
In the binary representation of a byte, check whether a given bit index is set to 1 or not.
The bit index must be between 1-8 or a runtime error will be produced.
| Argument | Type | Description | Default |
|---|---|---|---|
| i | Byte |
The byte whose bits are being inspected. | - |
| bit_index | Int |
The index of the bit to check (1-indexed, range 1-8). | - |
Return: Whether or not the given bit index is set to 1 in the byte.
Example:
assert Byte(6).get_bit(1) == no
assert Byte(6).get_bit(2) == yes
assert Byte(6).get_bit(3) == yes
assert Byte(6).get_bit(4) == no
Byte.hex
Byte.hex : func(byte: Byte, uppercase: Bool = yes, prefix: Bool = no -> Text)
Convert a byte to a hexidecimal text representation.
| Argument | Type | Description | Default |
|---|---|---|---|
| byte | Byte |
The byte to convert to hex. | - |
| uppercase | Bool |
Whether or not to use uppercase hexidecimal letters. | yes |
| prefix | Bool |
Whether or not to prepend a 0x prefix. |
no |
Return: The byte as a hexidecimal text.
Example:
assert Byte(18).hex(prefix=yes) == "0x12"
Byte.is_between
Byte.is_between : func(x: Byte, low: Byte, high: Byte -> Bool)
Determines if an integer is between two numbers (inclusive).
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Byte |
The integer to be checked. | - |
| low | Byte |
One end of the range to check (inclusive); | - |
| high | Byte |
The other end of the range to check (inclusive); | - |
Return: yes if a <= x and x <= b or b <= x and x <= a, otherwise no
Example:
assert Byte(7).is_between(1, 10) == yes
assert Byte(7).is_between(10, 1) == yes
assert Byte(7).is_between(100, 200) == no
assert Byte(7).is_between(1, 7) == yes
Byte.parse
Byte.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Byte?)
Parse a byte literal from text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to parse. | - |
| base | Int? |
The numeric base to use when parsing the byte. If unspecified, the byte's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | none |
| remainder | &Text? |
If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | none |
Return: The byte parsed from the text, if successful, otherwise none.
Example:
assert Byte.parse("5") == Byte(5)
assert Byte.parse("asdf") == none
assert Byte.parse("123xyz") == none
remainder : Text
assert Byte.parse("123xyz", remainder=&remainder) == Byte(123)
assert remainder == "xyz"
Byte.to
Byte.to : func(first: Byte, last: Byte, step: Int8? = none -> func(->Byte?))
Returns an iterator function that iterates over the range of bytes specified.
| Argument | Type | Description | Default |
|---|---|---|---|
| first | Byte |
The starting value of the range. | - |
| last | Byte |
The ending value of the range. | - |
| step | Int8? |
An optional step size to use. If unspecified or none, the step will be inferred to be +1 if last >= first, otherwise -1. |
none |
Return: An iterator function that returns each byte in the given range (inclusive).
Example:
iter := Byte(2).to(4)
assert iter() == Byte(2)
assert iter() == Byte(3)
assert iter() == Byte(4)
assert iter() == none
assert [x for x in Byte(2).to(5)] == [Byte(2), Byte(3), Byte(4), Byte(5)]
assert [x for x in Byte(5).to(2)] == [Byte(5), Byte(4), Byte(3), Byte(2)]
assert [x for x in Byte(2).to(5, step=2)] == [Byte(2), Byte(4)]
CString
CString.as_text
CString.as_text : func(str: CString -> Text)
Convert a C string to Text.
| Argument | Type | Description | Default |
|---|---|---|---|
| str | CString |
The C string. | - |
Return: The C string as a Text.
Example:
assert CString("Hello").as_text() == "Hello"
CString.join
CString.join : func(glue: CString, pieces: [CString] -> CString)
Join a list of C strings together with a separator.
| Argument | Type | Description | Default |
|---|---|---|---|
| glue | CString |
The C joiner used to between elements. | - |
| pieces | [CString] |
A list of C strings to join. | - |
Return: A C string of the joined together bits.
Example:
assert CString(",").join([CString("a"), CString("b")]) == CString("a,b")
Int
Int.abs
Int.abs : func(x: Int -> Int)
Calculates the absolute value of an integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Int |
The integer whose absolute value is to be calculated. | - |
Return: The absolute value of x.
Example:
assert (-10).abs() == 10
Int.choose
Int.choose : func(n: Int, k: Int -> Int)
Computes the binomial coefficient of the given numbers (the equivalent of n choose k in combinatorics). This is equal to n.factorial()/(k.factorial() * (n-k).factorial()).
| Argument | Type | Description | Default |
|---|---|---|---|
| n | Int |
The number of things to choose from. | - |
| k | Int |
The number of things to be chosen. | - |
Return: The binomial coefficient, equivalent to the number of ways to uniquely choose k objects from among n objects, ignoring order.
Example:
assert 4.choose(2) == 6
Int.clamped
Int.clamped : func(x: Int, low: Int, high: Int -> Int)
Returns the given number clamped between two values so that it is within that range.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Int |
The integer to clamp. | - |
| low | Int |
The lowest value the result can take. | - |
| high | Int |
The highest value the result can take. | - |
Return: The first argument clamped between the other two arguments.
Example:
assert 2.clamped(5, 10) == 5
Int.factorial
Int.factorial : func(n: Int -> Text)
Computes the factorial of an integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| n | Int |
The integer to compute the factorial of. | - |
Return: The factorial of the given integer.
Example:
assert 10.factorial() == 3628800
Int.get_bit
Int.get_bit : func(i: Int, bit_index: Int -> Bool)
In the binary representation of an integer, check whether a given bit index is set to 1 or not.
For fixed-size integers, the bit index must be between 1 and the number of bits in that integer (i.e. 1-64 for Int64). For Int, the bit index must be between 1 and Int64.max. Values outside this range will produce a runtime error.
| Argument | Type | Description | Default |
|---|---|---|---|
| i | Int |
The integer whose bits are being inspected. | - |
| bit_index | Int |
The index of the bit to check (1-indexed). | - |
Return: Whether or not the given bit index is set to 1 in the binary representation of the integer.
Example:
assert 6.get_bit(1) == no
assert 6.get_bit(2) == yes
assert 6.get_bit(3) == yes
assert 6.get_bit(4) == no
Int.hex
Int.hex : func(i: Int, digits: Int = 0, uppercase: Bool = yes, prefix: Bool = yes -> Text)
Converts an integer to its hexadecimal representation.
| Argument | Type | Description | Default |
|---|---|---|---|
| i | Int |
The integer to be converted. | - |
| digits | Int |
The minimum number of digits in the output string. | 0 |
| uppercase | Bool |
Whether to use uppercase letters for hexadecimal digits. | yes |
| prefix | Bool |
Whether to include a "0x" prefix. | yes |
Return: The hexadecimal string representation of the integer.
Example:
assert 255.hex(digits=4, uppercase=yes, prefix=yes) == "0x00FF"
Int.is_between
Int.is_between : func(x: Int, a: Int, b: Int -> Bool)
Determines if an integer is between two numbers (inclusive).
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Int |
The integer to be checked. | - |
| a | Int |
One end of the range to check (inclusive). | - |
| b | Int |
The other end of the range to check (inclusive). | - |
Return: yes if a <= x and x <= b or a >= x and x >= b, otherwise no
Example:
assert 7.is_between(1, 10) == yes
assert 7.is_between(10, 1) == yes
assert 7.is_between(100, 200) == no
assert 7.is_between(1, 7) == yes
Int.is_prime
Int.is_prime : func(x: Int, reps: Int = 50 -> Bool)
Determines if an integer is a prime number.
This function is probabilistic. With the default arguments, the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See the GNU MP docs for more details.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Int |
The integer to be checked. | - |
| reps | Int |
The number of repetitions for primality tests. | 50 |
Return: yes if x is a prime number, no otherwise.
Example:
assert 7.is_prime() == yes
assert 6.is_prime() == no
Int.next_prime
Int.next_prime : func(x: Int -> Int)
Finds the next prime number greater than the given integer.
This function is probabilistic, but the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See the GNU MP docs for more details.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Int |
The integer after which to find the next prime. | - |
Return: The next prime number greater than x.
Example:
assert 11.next_prime() == 13
Int.octal
Int.octal : func(i: Int, digits: Int = 0, prefix: Bool = yes -> Text)
Converts an integer to its octal representation.
| Argument | Type | Description | Default |
|---|---|---|---|
| i | Int |
The integer to be converted. | - |
| digits | Int |
The minimum number of digits in the output string. | 0 |
| prefix | Bool |
Whether to include a "0o" prefix. | yes |
Return: The octal string representation of the integer.
Example:
assert 64.octal(digits=4, prefix=yes) == "0o0100"
Int.onward
Int.onward : func(first: Int, step: Int = 1 -> Text)
Return an iterator that counts infinitely from the starting integer (with an optional step size).
| Argument | Type | Description | Default |
|---|---|---|---|
| first | Int |
The starting integer. | - |
| step | Int |
The increment step size. | 1 |
Return: An iterator function that counts onward from the starting integer.
Example:
nums : &[Int] = &[]
for i in 5.onward()
nums.insert(i)
stop if i == 10
assert nums[] == [5, 6, 7, 8, 9, 10]
Int.parse
Int.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Int?)
Converts a text representation of an integer into an integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text containing the integer. | - |
| base | Int? |
The numeric base to use when parsing the integer. If unspecified, the integer's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | none |
| remainder | &Text? |
If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | none |
Return: The integer represented by the text. If the given text contains a value outside of the representable range or if the entire text can't be parsed as an integer, none will be returned.
Example:
assert Int.parse("123") == 123
assert Int.parse("0xFF") == 255
assert Int.parse("123xyz") == none
remainder : Text
assert Int.parse("123xyz", remainder=&remainder) == 123
assert remainder == "xyz"
# Can't parse:
assert Int.parse("asdf") == none
# Outside valid range:
assert Int8.parse("9999999") == none
# Explicitly specifying base:
assert Int.parse("10", base=16) == 16
Int.sqrt
Int.sqrt : func(x: Int -> Int)
Calculates the nearest square root of an integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Int |
The integer whose square root is to be calculated. | - |
Return: The integer part of the square root of x.
Example:
assert 16.sqrt() == 4
assert 17.sqrt() == 4
Int.to
Int.to : func(first: Int, last: Int, step: Int? = none -> func(->Int?))
Returns an iterator function that iterates over the range of numbers specified.
| Argument | Type | Description | Default |
|---|---|---|---|
| first | Int |
The starting value of the range. | - |
| last | Int |
The ending value of the range. | - |
| step | Int? |
An optional step size to use. If unspecified or none, the step will be inferred to be +1 if last >= first, otherwise -1. |
none |
Return: An iterator function that returns each integer in the given range (inclusive).
Example:
iter := 2.to(5)
assert iter() == 2
assert iter() == 3
assert iter() == 4
assert iter() == 5
assert iter() == none
assert [x for x in 2.to(5)] == [2, 3, 4, 5]
assert [x for x in 5.to(2)] == [5, 4, 3, 2]
assert [x for x in 2.to(5, step=2)] == [2, 4]
List
List.binary_search
List.binary_search : func(list: [T], by: func(x,y:&T->Int32) = T.compare -> Int)
Performs a binary search on a sorted list.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The sorted list to search. | - |
| by | func(x,y:&T->Int32) |
The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | T.compare |
Return: Assuming the input list is sorted according to the given comparison function, return the index where the given item would be inserted to maintain the sorted order. That is, if the item is found, return its index, otherwise return the place where it would be found if it were inserted and the list were sorted.
Example:
assert [1, 3, 5, 7, 9].binary_search(5) == 3
assert [1, 3, 5, 7, 9].binary_search(-999) == 1
assert [1, 3, 5, 7, 9].binary_search(999) == 6
List.by
List.by : func(list: [T], step: Int -> [T])
Creates a new list with elements spaced by the specified step value.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The original list. | - |
| step | Int |
The step value for selecting elements. | - |
Return: A new list with every step-th element from the original list.
Example:
assert [1, 2, 3, 4, 5, 6].by(2) == [1, 3, 5]
List.clear
List.clear : func(list: @[T] -> Void)
Clears all elements from the list.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list to be cleared. | - |
Return: Nothing.
Example:
list := &[10, 20]
list.clear()
assert list[] == []
List.counts
List.counts : func(list: [T] -> {T=Int})
Counts the occurrences of each element in the list.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to count elements in. | - |
Return: A table mapping each element to its count.
Example:
assert [10, 20, 30, 30, 30].counts() == {10:1, 20:1, 30:3}
List.find
List.find : func(list: [T], target: T -> Int?)
Finds the index of the first occurrence of an element (if any).
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to search through. | - |
| target | T |
The item to search for. | - |
Return: The index of the first occurrence or none if not found.
Example:
assert [10, 20, 30, 40, 50].find(20) == 2
assert [10, 20, 30, 40, 50].find(9999) == none
List.from
List.from : func(list: [T], first: Int -> [T])
Returns a slice of the list starting from a specified index.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The original list. | - |
| first | Int |
The index to start from. | - |
Return: A new list starting from the specified index.
Example:
assert [10, 20, 30, 40, 50].from(3) == [30, 40, 50]
List.has
List.has : func(list: [T], target: T -> Bool)
Checks if the list has an element.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to check. | - |
| target | T |
The element to check for. | - |
Return: yes if the list has the element, no otherwise.
Example:
assert [10, 20, 30].has(20) == yes
List.heap_pop
List.heap_pop : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> T?)
Removes and returns the top element of a heap or none if the list is empty. By default, this is the minimum value in the heap.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the heap. | - |
| by | func(x,y:&T->Int32) |
The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | T.compare |
Return: The removed top element of the heap or none if the list is empty.
Example:
my_heap := &[30, 10, 20]
my_heap.heapify()
assert my_heap.heap_pop() == 10
List.heap_push
List.heap_push : func(list: @[T], item: T, by = T.compare -> Void)
Adds an element to the heap and maintains the heap property. By default, this is a minimum heap.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the heap. | - |
| item | T |
The item to be added. | - |
| by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | T.compare |
Return: Nothing.
Example:
my_heap : &[Int]
my_heap.heap_push(10)
assert my_heap.heap_pop() == 10
List.heapify
List.heapify : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> Void)
Converts a list into a heap.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list to be heapified. | - |
| by | func(x,y:&T->Int32) |
The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | T.compare |
Return: Nothing.
Example:
my_heap := &[30, 10, 20]
my_heap.heapify()
List.insert
List.insert : func(list: @[T], item: T, at: Int = 0 -> Void)
Inserts an element at a specified position in the list.
Since indices are 1-indexed and negative indices mean "starting from the back", an index of 0 means "after the last item".
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list. | - |
| item | T |
The item to be inserted. | - |
| at | Int |
The index at which to insert the item. | 0 |
Return: Nothing.
Example:
list := &[10, 20]
list.insert(30)
assert list == [10, 20, 30]
list.insert(999, at=2)
assert list == [10, 999, 20, 30]
List.insert_all
List.insert_all : func(list: @[T], items: [T], at: Int = 0 -> Void)
Inserts a list of items at a specified position in the list.
Since indices are 1-indexed and negative indices mean "starting from the back", an index of 0 means "after the last item".
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list. | - |
| items | [T] |
The items to be inserted. | - |
| at | Int |
The index at which to insert the item. | 0 |
Return: Nothing.
Example:
list := &[10, 20]
list.insert_all([30, 40])
assert list == [10, 20, 30, 40]
list.insert_all([99, 100], at=2)
assert list == [10, 99, 100, 20, 30, 40]
List.pop
List.pop : func(list: &[T], index: Int = -1 -> T?)
Removes and returns an item from the list. If the given index is present in the list, the item at that index will be removed and the list will become one element shorter.
Since negative indices are counted from the back, the default behavior is to pop the last value.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | &[T] |
The list to remove an item from. | - |
| index | Int |
The index from which to remove the item. | -1 |
Return: none if the list is empty or the given index does not exist in the list, otherwise the item at the given index.
Example:
list := &[10, 20, 30, 40]
assert list.pop() == 40
assert list[] == [10, 20, 30]
assert list.pop(index=2) == 20
assert list[] == [10, 30]
List.random
List.random : func(list: [T], random: func(min,max:Int64->Int64)? = none -> T?)
Selects a random element from the list.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list from which to select a random element. | - |
| random | func(min,max:Int64->Int64)? |
If provided, this function will be used to get a random index in the list. Returned values must be between min and max (inclusive). (Used for deterministic pseudorandom number generation) |
none |
Return: A random element from the list or none if the list is empty.
Example:
nums := [10, 20, 30]
pick := nums.random()!
assert nums.has(pick)
empty : [Int]
assert empty.random() == none
List.remove_at
List.remove_at : func(list: @[T], at: Int = -1, count: Int = 1 -> Void)
Removes elements from the list starting at a specified index.
Since negative indices are counted from the back, the default behavior is to remove the last item.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list. | - |
| at | Int |
The index at which to start removing elements. | -1 |
| count | Int |
The number of elements to remove. | 1 |
Return: Nothing.
Example:
list := &[10, 20, 30, 40, 50]
list.remove_at(2)
assert list == [10, 30, 40, 50]
list.remove_at(2, count=2)
assert list == [10, 50]
List.remove_item
List.remove_item : func(list: @[T], item: T, max_count: Int = -1 -> Void)
Removes all occurrences of a specified item from the list.
A negative max_count means "remove all occurrences".
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list. | - |
| item | T |
The item to be removed. | - |
| max_count | Int |
The maximum number of occurrences to remove. | -1 |
Return: Nothing.
Example:
list := &[10, 20, 10, 20, 30]
list.remove_item(10)
assert list == [20, 20, 30]
list.remove_item(20, max_count=1)
assert list == [20, 30]
List.reversed
List.reversed : func(list: [T] -> [T])
Returns a reversed slice of the list.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to be reversed. | - |
Return: A slice of the list with elements in reverse order.
Example:
assert [10, 20, 30].reversed() == [30, 20, 10]
List.sample
List.sample : func(list: [T], count: Int, weights: [Num]? = none, random: func(->Num)? = none -> [T])
Selects a sample of elements from the list, optionally with weighted probabilities.
Errors will be raised if any of the following conditions occurs: - The given list has no elements and count >= 1 - count < 0 (negative count) - The number of weights provided doesn't match the length of the list. - Any weight in the weights list is negative, infinite, or NaN - The sum of the given weights is zero (zero probability for every element).
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to sample from. | - |
| count | Int |
The number of elements to sample. | - |
| weights | [Num]? |
The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. | none |
| random | func(->Num)? |
If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between 0.0 (inclusive) and 1.0 (exclusive). (Used for deterministic pseudorandom number generation) |
none |
Return: A list of sampled elements from the list.
Example:
_ := [10, 20, 30].sample(2, weights=[90%, 5%, 5%]) # E.g. [10, 10]
List.shuffle
List.shuffle : func(list: @[T], random: func(min,max:Int64->Int64)? = none -> Void)
Shuffles the elements of the list in place.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list to be shuffled. | - |
| random | func(min,max:Int64->Int64)? |
If provided, this function will be used to get a random index in the list. Returned values must be between min and max (inclusive). (Used for deterministic pseudorandom number generation) |
none |
Return: Nothing.
Example:
nums := &[10, 20, 30, 40]
nums.shuffle()
# E.g. [20, 40, 10, 30]
List.shuffled
List.shuffled : func(list: [T], random: func(min,max:Int64->Int64)? = none -> [T])
Creates a new list with elements shuffled.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to be shuffled. | - |
| random | func(min,max:Int64->Int64)? |
If provided, this function will be used to get a random index in the list. Returned values must be between min and max (inclusive). (Used for deterministic pseudorandom number generation) |
none |
Return: A new list with shuffled elements.
Example:
nums := [10, 20, 30, 40]
_ := nums.shuffled()
# E.g. [20, 40, 10, 30]
List.slice
List.slice : func(list: [T], from: Int, to: Int -> [T])
Returns a slice of the list spanning the given indices (inclusive).
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The original list. | - |
| from | Int |
The first index to include. | - |
| to | Int |
The last index to include. | - |
Return: A new list spanning the given indices. Note: negative indices are counted from the back of the list, so -1 refers to the last element, -2 the second-to-last, and so on.
Example:
assert [10, 20, 30, 40, 50].slice(2, 4) == [20, 30, 40]
assert [10, 20, 30, 40, 50].slice(-3, -2) == [30, 40]
List.sort
List.sort : func(list: @[T], by = T.compare -> Void)
Sorts the elements of the list in place in ascending order (small to large).
| Argument | Type | Description | Default |
|---|---|---|---|
| list | @[T] |
The mutable reference to the list to be sorted. | - |
| by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | T.compare |
Return: Nothing.
Example:
list := &[40, 10, -30, 20]
list.sort()
assert list == [-30, 10, 20, 40]
list.sort(func(a,b:&Int) a.abs() <> b.abs())
assert list == [10, 20, -30, 40]
List.sorted
List.sorted : func(list: [T], by = T.compare -> [T])
Creates a new list with elements sorted.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to be sorted. | - |
| by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | T.compare |
Return: A new list with sorted elements.
Example:
assert [40, 10, -30, 20].sorted() == [-30, 10, 20, 40]
assert [40, 10, -30, 20].sorted(
func(a,b:&Int) a.abs() <> b.abs()
) == [10, 20, -30, 40]
List.to
List.to : func(list: [T], last: Int -> [T])
Returns a slice of the list from the start of the original list up to a specified index (inclusive).
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The original list. | - |
| last | Int |
The index up to which elements should be included. | - |
Return: A new list containing elements from the start up to the specified index.
Example:
assert [10, 20, 30, 40, 50].to(3) == [10, 20, 30]
assert [10, 20, 30, 40, 50].to(-2) == [10, 20, 30, 40]
List.unique
List.unique : func(list: [T] -> {T})
Returns a set of the unique elements of the list.
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to process. | - |
Return: A set of the unique elements from the list.
Example:
assert [10, 20, 10, 10, 30].unique() == {10, 20, 30}
List.where
List.where : func(list: [T], predicate: func(item:&T -> Bool) -> Int)
Find the index of the first item that matches a predicate function (if any).
| Argument | Type | Description | Default |
|---|---|---|---|
| list | [T] |
The list to search through. | - |
| predicate | func(item:&T -> Bool) |
A function that returns yes if the item's index should be returned or no if it should not. |
- |
Return: Returns the index of the first item where the predicate is true or none if no item matches.
Example:
assert ["BC", "ABC", "CD"].where(func(t:&Text) t.starts_with("A")) == 2
assert ["BC", "ABC", "CD"].where(func(t:&Text) t.starts_with("X")) == none
Num
Num.1_PI
Num.1_PI : Num
The constant $\frac{1}{\pi}$.
Num.2_PI
Num.2_PI : Num
The constant $2 \times \pi$.
Num.2_SQRTPI
Num.2_SQRTPI : Num
The constant $2 \times \sqrt{\pi}$.
Num.E
Num.E : Num
The base of the natural logarithm ($e$).
Num.INF
Num.INF : Num
Positive infinity.
Num.LN10
Num.LN10 : Num
The natural logarithm of 10.
Num.LN2
Num.LN2 : Num
The natural logarithm of 2.
Num.LOG2E
Num.LOG2E : Num
The base 2 logarithm of $e$
Num.PI
Num.PI : Num
Pi ($\pi$).
Num.PI_2
Num.PI_2 : Num
$\frac{\pi}{2}$
Num.PI_4
Num.PI_4 : Num
$\frac{\pi}{4}$
Num.SQRT1_2
Num.SQRT1_2 : Num
$\sqrt{\frac{1}{2}}$
Num.SQRT2
Num.SQRT2 : Num
$\sqrt{2}$
Num.TAU
Num.TAU : Num
Tau ($2 \times \pi$)
Num.abs
Num.abs : func(n: Num -> Num)
Calculates the absolute value of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| n | Num |
The number whose absolute value is to be computed. | - |
Return: The absolute value of n.
Example:
assert (-3.5).abs() == 3.5
Num.acos
Num.acos : func(x: Num -> Num)
Computes the arc cosine of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the arc cosine is to be calculated. | - |
Return: The arc cosine of x in radians.
Example:
assert (0.0).acos().near(1.5707963267948966)
Num.acosh
Num.acosh : func(x: Num -> Num)
Computes the inverse hyperbolic cosine of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the inverse hyperbolic cosine is to be calculated. | - |
Return: The inverse hyperbolic cosine of x.
Example:
assert (1.0).acosh() == 0
Num.asin
Num.asin : func(x: Num -> Num)
Computes the arc sine of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the arc sine is to be calculated. | - |
Return: The arc sine of x in radians.
Example:
assert (0.5).asin().near(0.5235987755982989)
Num.asinh
Num.asinh : func(x: Num -> Num)
Computes the inverse hyperbolic sine of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the inverse hyperbolic sine is to be calculated. | - |
Return: The inverse hyperbolic sine of x.
Example:
assert (0.0).asinh() == 0
Num.atan
Num.atan : func(x: Num -> Num)
Computes the arc tangent of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the arc tangent is to be calculated. | - |
Return: The arc tangent of x in radians.
Example:
assert (1.0).atan().near(0.7853981633974483)
Num.atan2
Num.atan2 : func(x: Num, y: Num -> Num)
Computes the arc tangent of the quotient of two numbers.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The numerator. | - |
| y | Num |
The denominator. | - |
Return: The arc tangent of x/y in radians.
Example:
assert Num.atan2(1, 1).near(0.7853981633974483)
Num.atanh
Num.atanh : func(x: Num -> Num)
Computes the inverse hyperbolic tangent of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the inverse hyperbolic tangent is to be calculated. | - |
Return: The inverse hyperbolic tangent of x.
Example:
assert (0.5).atanh().near(0.5493061443340549)
Num.cbrt
Num.cbrt : func(x: Num -> Num)
Computes the cube root of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the cube root is to be calculated. | - |
Return: The cube root of x.
Example:
assert (27.0).cbrt() == 3
Num.ceil
Num.ceil : func(x: Num -> Num)
Rounds a number up to the nearest integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number to be rounded up. | - |
Return: The smallest integer greater than or equal to x.
Example:
assert (3.2).ceil() == 4
Num.clamped
Num.clamped : func(x: Num, low: Num, high: Num -> Num)
Returns the given number clamped between two values so that it is within that range.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number to clamp. | - |
| low | Num |
The lowest value the result can take. | - |
| high | Num |
The highest value the result can take. | - |
Return: The first argument clamped between the other two arguments.
Example:
assert (2.5).clamped(5.5, 10.5) == 5.5
Num.copysign
Num.copysign : func(x: Num, y: Num -> Num)
Copies the sign of one number to another.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number whose magnitude will be copied. | - |
| y | Num |
The number whose sign will be copied. | - |
Return: A number with the magnitude of x and the sign of y.
Example:
assert (3.0).copysign(-1) == -3
Num.cos
Num.cos : func(x: Num -> Num)
Computes the cosine of a number (angle in radians).
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The angle in radians. | - |
Return: The cosine of x.
Example:
assert (0.0).cos() == 1
Num.cosh
Num.cosh : func(x: Num -> Num)
Computes the hyperbolic cosine of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the hyperbolic cosine is to be calculated. | - |
Return: The hyperbolic cosine of x.
Example:
assert (0.0).cosh() == 1
Num.erf
Num.erf : func(x: Num -> Num)
Computes the error function of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the error function is to be calculated. | - |
Return: The error function of x.
Example:
assert (0.0).erf() == 0
Num.erfc
Num.erfc : func(x: Num -> Num)
Computes the complementary error function of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the complementary error function is to be calculated. | - |
Return: The complementary error function of x.
Example:
assert (0.0).erfc() == 1
Num.exp
Num.exp : func(x: Num -> Num)
Computes the exponential function $e^x$ for a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The exponent. | - |
Return: The value of $e^x$.
Example:
assert (1.0).exp().near(2.718281828459045)
Num.exp2
Num.exp2 : func(x: Num -> Num)
Computes $2^x$ for a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The exponent. | - |
Return: The value of $2^x$.
Example:
assert (3.0).exp2() == 8
Num.expm1
Num.expm1 : func(x: Num -> Num)
Computes $e^x - 1$ for a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The exponent. | - |
Return: The value of $e^x - 1$.
Example:
assert (1.0).expm1().near(1.7182818284590453)
Num.fdim
Num.fdim : func(x: Num, y: Num -> Num)
Computes the positive difference between two numbers.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The first number. | - |
| y | Num |
The second number. | - |
Return: The positive difference $\max(0, x - y)$.
Example:
assert (5.0).fdim(3) == 2
Num.floor
Num.floor : func(x: Num -> Num)
Rounds a number down to the nearest integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number to be rounded down. | - |
Return: The largest integer less than or equal to x.
Example:
assert (3.7).floor() == 3
Num.hypot
Num.hypot : func(x: Num, y: Num -> Num)
Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The first number. | - |
| y | Num |
The second number. | - |
Return: The Euclidean norm of x and y.
Example:
assert Num.hypot(3, 4) == 5
Num.is_between
Num.is_between : func(x: Num, low: Num, high: Num -> Bool)
Determines if a number is between two numbers (inclusive).
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The integer to be checked. | - |
| low | Num |
One end of the range to check (inclusive). | - |
| high | Num |
The other end of the range to check (inclusive). | - |
Return: yes if a <= x and x <= b or b <= x and x <= a, otherwise no
Example:
assert (7.5).is_between(1, 10) == yes
assert (7.5).is_between(10, 1) == yes
assert (7.5).is_between(100, 200) == no
assert (7.5).is_between(1, 7.5) == yes
Num.isfinite
Num.isfinite : func(n: Num -> Bool)
Checks if a number is finite.
| Argument | Type | Description | Default |
|---|---|---|---|
| n | Num |
The number to be checked. | - |
Return: yes if n is finite, no otherwise.
Example:
assert (1.0).isfinite() == yes
assert Num.INF.isfinite() == no
Num.isinf
Num.isinf : func(n: Num -> Bool)
Checks if a number is infinite.
| Argument | Type | Description | Default |
|---|---|---|---|
| n | Num |
The number to be checked. | - |
Return: yes if n is infinite, no otherwise.
Example:
assert Num.INF.isinf() == yes
assert (1.0).isinf() == no
Num.j0
Num.j0 : func(x: Num -> Num)
Computes the Bessel function of the first kind of order 0.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the Bessel function is to be calculated. | - |
Return: The Bessel function of the first kind of order 0 of x.
Example:
assert (0.0).j0() == 1
Num.j1
Num.j1 : func(x: Num -> Num)
Computes the Bessel function of the first kind of order 1.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the Bessel function is to be calculated. | - |
Return: The Bessel function of the first kind of order 1 of x.
Example:
assert (0.0).j1() == 0
Num.log
Num.log : func(x: Num -> Num)
Computes the natural logarithm (base $e$) of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the natural logarithm is to be calculated. | - |
Return: The natural logarithm of x.
Example:
assert Num.E.log() == 1
Num.log10
Num.log10 : func(x: Num -> Num)
Computes the base-10 logarithm of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the base-10 logarithm is to be calculated. | - |
Return: The base-10 logarithm of x.
Example:
assert (100.0).log10() == 2
Num.log1p
Num.log1p : func(x: Num -> Num)
Computes $\log(1 + x)$ for a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which $\log(1 + x)$ is to be calculated. | - |
Return: The value of $\log(1 + x)$.
Example:
assert (1.0).log1p().near(0.6931471805599453)
Num.log2
Num.log2 : func(x: Num -> Num)
Computes the base-2 logarithm of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the base-2 logarithm is to be calculated. | - |
Return: The base-2 logarithm of x.
Example:
assert (8.0).log2() == 3
Num.logb
Num.logb : func(x: Num -> Num)
Computes the binary exponent (base-2 logarithm) of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the binary exponent is to be calculated. | - |
Return: The binary exponent of x.
Example:
assert (8.0).logb() == 3
Num.mix
Num.mix : func(amount: Num, x: Num, y: Num -> Num)
Interpolates between two numbers based on a given amount.
| Argument | Type | Description | Default |
|---|---|---|---|
| amount | Num |
The interpolation factor (between 0 and 1). |
- |
| x | Num |
The starting number. | - |
| y | Num |
The ending number. | - |
Return: The interpolated number between x and y based on amount.
Example:
assert (0.5).mix(10, 20) == 15
assert (0.25).mix(10, 20) == 12.5
Num.near
Num.near : func(x: Num, y: Num, ratio: Num = 1e-9, min_epsilon: Num = 1e-9 -> Bool)
Checks if two numbers are approximately equal within specified tolerances. If two numbers are within an absolute difference or the ratio between the two is small enough, they are considered near each other.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The first number. | - |
| y | Num |
The second number. | - |
| ratio | Num |
The relative tolerance. Default is 1e-9. |
1e-9 |
| min_epsilon | Num |
The absolute tolerance. Default is 1e-9. |
1e-9 |
Return: yes if x and y are approximately equal within the specified tolerances, no otherwise.
Example:
assert (1.0).near(1.000000001) == yes
assert (100.0).near(110, ratio=0.1) == yes
assert (5.0).near(5.1, min_epsilon=0.1) == yes
Num.nextafter
Num.nextafter : func(x: Num, y: Num -> Num)
Computes the next representable value after a given number towards a specified direction.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The starting number. | - |
| y | Num |
The direction towards which to find the next representable value. | - |
Return: The next representable value after x in the direction of y.
Example:
assert (1.0).nextafter(1.1) == 1.0000000000000002
Num.parse
Num.parse : func(text: Text, remainder: &Text? = none -> Num?)
Converts a text representation of a number into a floating-point number.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text containing the number. | - |
| remainder | &Text? |
If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | none |
Return: The number represented by the text or none if the entire text can't be parsed as a number.
Example:
assert Num.parse("3.14") == 3.14
assert Num.parse("1e3") == 1000
assert Num.parse("1.5junk") == none
remainder : Text
assert Num.parse("1.5junk", &remainder) == 1.5
assert remainder == "junk"
Num.percent
Num.percent : func(n: Num, precision: Num = 0.01 -> Text)
Convert a number into a percentage text with a percent sign.
| Argument | Type | Description | Default |
|---|---|---|---|
| n | Num |
The number to be converted to a percent. | - |
| precision | Num |
Round the percentage to this precision level. | 0.01 |
Return: A text representation of the number as a percentage with a percent sign.
Example:
assert (0.5).percent() == "50%"
assert (1./3.).percent(2) == "34%"
assert (1./3.).percent(precision=0.0001) == "33.3333%"
assert (1./3.).percent(precision=10.) == "30%"
Num.rint
Num.rint : func(x: Num -> Num)
Rounds a number to the nearest integer, with ties rounded to the nearest even integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number to be rounded. | - |
Return: The nearest integer value of x.
Example:
assert (3.5).rint() == 4
assert (2.5).rint() == 2
Num.round
Num.round : func(x: Num -> Num)
Rounds a number to the nearest whole number integer.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number to be rounded. | - |
Return: The nearest integer value of x.
Example:
assert (2.3).round() == 2
assert (2.7).round() == 3
Num.significand
Num.significand : func(x: Num -> Num)
Extracts the significand (or mantissa) of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number from which to extract the significand. | - |
Return: The significand of x.
Example:
assert (1234.567).significand() == 1.2056318359375
Num.sin
Num.sin : func(x: Num -> Num)
Computes the sine of a number (angle in radians).
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The angle in radians. | - |
Return: The sine of x.
Example:
assert (0.0).sin() == 0
Num.sinh
Num.sinh : func(x: Num -> Num)
Computes the hyperbolic sine of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the hyperbolic sine is to be calculated. | - |
Return: The hyperbolic sine of x.
Example:
assert (0.0).sinh() == 0
Num.sqrt
Num.sqrt : func(x: Num -> Num)
Computes the square root of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the square root is to be calculated. | - |
Return: The square root of x.
Example:
assert (16.0).sqrt() == 4
Num.tan
Num.tan : func(x: Num -> Num)
Computes the tangent of a number (angle in radians).
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The angle in radians. | - |
Return: The tangent of x.
Example:
assert (0.0).tan() == 0
Num.tanh
Num.tanh : func(x: Num -> Num)
Computes the hyperbolic tangent of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the hyperbolic tangent is to be calculated. | - |
Return: The hyperbolic tangent of x.
Example:
assert (0.0).tanh() == 0
Num.tgamma
Num.tgamma : func(x: Num -> Num)
Computes the gamma function of a number.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the gamma function is to be calculated. | - |
Return: The gamma function of x.
Example:
assert (1.0).tgamma() == 1
Num.trunc
Num.trunc : func(x: Num -> Num)
Truncates a number to the nearest integer towards zero.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number to be truncated. | - |
Return: The integer part of x towards zero.
Example:
assert (3.7).trunc() == 3
assert (-3.7).trunc() == -3
Num.with_precision
Num.with_precision : func(n: Num, precision: Num -> Num)
Round a number to the given precision level (specified as 10, .1, .001 etc).
| Argument | Type | Description | Default |
|---|---|---|---|
| n | Num |
The number to be rounded to a given precision. | - |
| precision | Num |
The precision to which the number should be rounded. | - |
Return: The number, rounded to the given precision level.
Example:
assert (0.1234567).with_precision(0.01) == 0.12
assert (123456.).with_precision(100) == 123500
assert (1234567.).with_precision(5) == 1234565
Num.y0
Num.y0 : func(x: Num -> Num)
Computes the Bessel function of the second kind of order 0.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the Bessel function is to be calculated. | - |
Return: The Bessel function of the second kind of order 0 of x.
Example:
assert (1.0).y0().near(0.08825696421567698)
Num.y1
Num.y1 : func(x: Num -> Num)
Computes the Bessel function of the second kind of order 1.
| Argument | Type | Description | Default |
|---|---|---|---|
| x | Num |
The number for which the Bessel function is to be calculated. | - |
Return: The Bessel function of the second kind of order 1 of x.
Example:
assert (1.0).y1().near(-0.7812128213002887)
Path
Path.accessed
Path.accessed : func(path: Path, follow_symlinks: Bool = yes -> Int64?)
Gets the file access time of a file.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file whose access time you want. | - |
| follow_symlinks | Bool |
Whether to follow symbolic links. | yes |
Return: A 64-bit unix epoch timestamp representing when the file or directory was last accessed, or none if no such file or directory exists.
Example:
assert (./file.txt).accessed() == Int64(1704221100)
assert (./not-a-file).accessed() == none
Path.append
Path.append : func(path: Path, text: Text, permissions: Int32 = Int32(0o644) -> Result)
Appends the given text to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to append to. | - |
| text | Text |
The text to append to the file. | - |
| permissions | Int32 |
The permissions to set on the file if it is being created. | Int32(0o644) |
Return: Either Success or Failure(reason).
Example:
(./log.txt).append("extra line\n")!
Path.append_bytes
Path.append_bytes : func(path: Path, bytes: [Byte], permissions: Int32 = Int32(0o644) -> Result)
Appends the given bytes to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to append to. | - |
| bytes | [Byte] |
The bytes to append to the file. | - |
| permissions | Int32 |
The permissions to set on the file if it is being created. | Int32(0o644) |
Return: Either Success or Failure(reason).
Example:
(./log.txt).append_bytes([104, 105])!
Path.base_name
Path.base_name : func(path: Path -> Text)
Returns the base name of the file or directory at the specified path.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file or directory. | - |
Return: The base name of the file or directory.
Example:
assert (./path/to/file.txt).base_name() == "file.txt"
Path.by_line
Path.by_line : func(path: Path -> func(->Text?)?)
Returns an iterator that can be used to iterate over a file one line at a time, or returns none if the file could not be opened.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file. | - |
Return: An iterator that can be used to get lines from a file one at a time or none if the file couldn't be read.
Example:
# Safely handle file not being readable:
if lines := (./file.txt).by_line()
for line in lines
say(line.upper())
else
say("Couldn't read file!")
# Assume the file is readable and error if that's not the case:
for line in (/dev/stdin).by_line()!
say(line.upper())
Path.byte_writer
Path.byte_writer : func(path: Path, append: Bool = no, permissions: Int32 = Int32(0o644) -> func(bytes:[Byte], close:Bool=no -> Result))
Returns a function that can be used to repeatedly write bytes to the same file.
The file writer will keep its file descriptor open after each write (unless the close argument is set to yes). If the file writer is never closed, it will be automatically closed when the file writer is garbage collected.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to write to. | - |
| append | Bool |
If set to yes, writes to the file will append. If set to no, then the first write to the file will overwrite its contents and subsequent calls will append. |
no |
| permissions | Int32 |
The permissions to set on the file if it is created. | Int32(0o644) |
Return: Returns a function that can repeatedly write bytes to the same file. If close is set to yes, then the file will be closed after writing. If this function is called again after closing, the file will be reopened for appending.
Example:
write := (./file.txt).byte_writer()
write("Hello\n".utf8())!
write("world\n".utf8(), close=yes)!
Path.can_execute
Path.can_execute : func(path: Path -> Bool)
Returns whether or not a file can be executed by the current user/group.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to check. | - |
Return: yes if the file or directory exists and the current user has execute permissions, otherwise no.
Example:
assert (/bin/sh).can_execute() == yes
assert (/usr/include/stdlib.h).can_execute() == no
assert (/non/existant/file).can_execute() == no
Path.can_read
Path.can_read : func(path: Path -> Bool)
Returns whether or not a file can be read by the current user/group.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to check. | - |
Return: yes if the file or directory exists and the current user has read permissions, otherwise no.
Example:
assert (/usr/include/stdlib.h).can_read() == yes
assert (/etc/shadow).can_read() == no
assert (/non/existant/file).can_read() == no
Path.can_write
Path.can_write : func(path: Path -> Bool)
Returns whether or not a file can be written by the current user/group.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to check. | - |
Return: yes if the file or directory exists and the current user has write permissions, otherwise no.
Example:
assert (/tmp).can_write() == yes
assert (/etc/passwd).can_write() == no
assert (/non/existant/file).can_write() == no
Path.changed
Path.changed : func(path: Path, follow_symlinks: Bool = yes -> Int64?)
Gets the file change time of a file.
This is the "ctime" of a file, which is not the file creation time.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file whose change time you want. | - |
| follow_symlinks | Bool |
Whether to follow symbolic links. | yes |
Return: A 64-bit unix epoch timestamp representing when the file or directory was last changed, or none if no such file or directory exists.
Example:
assert (./file.txt).changed() == Int64(1704221100)
assert (./not-a-file).changed() == none
Path.child
Path.child : func(path: Path, child: Text -> Path)
Return a path that is a child of another path.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of a directory. | - |
| child | Text |
The name of a child file or directory. | - |
Return: A new path representing the child.
Example:
assert (./directory).child("file.txt") == (./directory/file.txt)
Path.children
Path.children : func(path: Path, include_hidden = no -> [Path])
Returns a list of children (files and directories) within the directory at the specified path. Optionally includes hidden files. Child ordering is not specified.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the directory. | - |
| include_hidden | `` | Whether to include hidden files (those starting with a .). |
no |
Return: A list of paths for the children.
Example:
assert (./directory).children(include_hidden=yes) == [(./directory/.git), (./directory/foo.txt)]
Path.create_directory
Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Result)
Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the directory to create. | - |
| permissions | `` | The permissions to set on the new directory. | Int32(0o755) |
| recursive | `` | If set to yes, then recursively create any parent directories if they don't exist, otherwise fail if the parent directory does not exist. When set to yes, this function behaves like mkdir -p. |
yes |
Return: Either Success or Failure(reason).
Example:
(./new_directory).create_directory()!
Path.current_dir
Path.current_dir : func(-> Path)
Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed.
Return: The absolute path of the current directory.
Example:
assert Path.current_dir() == (/home/user/tomo)
Path.each_child
Path.each_child : func(path: Path, include_hidden = no -> func(->Path?)?)
Returns an iterator over the children (files and directories) within the directory at the specified path. Optionally includes hidden files. Iteration order is not specified.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the directory. | - |
| include_hidden | `` | Whether to include hidden files (those starting with a .). |
no |
Return: An iterator over the children in a directory or none if the path is not a directory or a symlink to a directory.
Example:
for child in (/dir).each_child()
say("Child: $child")
Path.exists
Path.exists : func(path: Path -> Bool)
Checks if a file or directory exists at the specified path.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to check. | - |
Return: True if the file or directory exists, False otherwise.
Example:
assert (/).exists() == yes
Path.expand_home
Path.expand_home : func(path: Path -> Path)
For home-based paths (those starting with ~), expand the path to replace the tilde with and absolute path to the user's $HOME directory.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to expand. | - |
Return: If the path does not start with a ~, then return it unmodified. Otherwise, replace the ~ with an absolute path to the user's home directory.
Example:
# Assume current user is 'user'
assert (~/foo).expand_home() == (/home/user/foo)
# No change
assert (/foo).expand_home() == (/foo)
Path.extension
Path.extension : func(path: Path, full: Bool = yes -> Text)
Returns the file extension of the file at the specified path. Optionally returns the full extension.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file. | - |
| full | Bool |
Whether to return everything after the first . in the base name, or only the last part of the extension. |
yes |
Return: The file extension (not including the leading .) or an empty text if there is no file extension.
Example:
assert (./file.tar.gz).extension() == "tar.gz"
assert (./file.tar.gz).extension(full=no) == "gz"
assert (/foo).extension() == ""
assert (./.git).extension() == ""
Path.files
Path.files : func(path: Path, include_hidden: Bool = no -> [Path])
Returns a list of files within the directory at the specified path. Optionally includes hidden files.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the directory. | - |
| include_hidden | Bool |
Whether to include hidden files (those starting with a .). |
no |
Return: A list of file paths.
Example:
assert (./directory).files(include_hidden=yes) == [(./directory/file1.txt), (./directory/file2.txt)]
Path.glob
Path.glob : func(path: Path -> [Path])
Perform a globbing operation and return a list of matching paths. Some glob specific details:
The paths "." and ".." are not included in any globbing results.
Files or directories that begin with "." will not match
*, but will match.*.Globs do support
{a,b}syntax for matching files that match any of several choices of patterns.The shell-style syntax
**for matching subdirectories is not supported.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the directory which may contain special globbing characters like *, ?, or {...} |
- |
Return: A list of file paths that match the glob.
Example:
# Current directory includes: foo.txt, baz.txt, qux.jpg, .hidden
assert (./*).glob() == [(./foo.txt), (./baz.txt), (./qux.jpg)]
assert (./*.txt).glob() == [(./foo.txt), (./baz.txt)]
assert (./*.{txt,jpg}).glob() == [(./foo.txt), (./baz.txt), (./qux.jpg)]
assert (./.*).glob() == [(./.hidden)]
# Globs with no matches return an empty list:
assert (./*.xxx).glob() == []
Path.group
Path.group : func(path: Path, follow_symlinks: Bool = yes -> Text?)
Get the owning group of a file or directory.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path whose owning group to get. | - |
| follow_symlinks | Bool |
Whether to follow symbolic links. | yes |
Return: The name of the group which owns the file or directory, or none if the path does not exist.
Example:
assert (/bin).group() == "root"
assert (/non/existent/file).group() == none
Path.has_extension
Path.has_extension : func(path: Path, extension: Text -> Bool)
Return whether or not a path has a given file extension.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
A path. | - |
| extension | Text |
A file extension (leading . is optional). If empty, the check will test if the file does not have any file extension. |
- |
Return: Whether or not the path has the given extension.
Example:
assert (/foo.txt).has_extension("txt") == yes
assert (/foo.txt).has_extension(".txt") == yes
assert (/foo.tar.gz).has_extension("gz") == yes
assert (/foo.tar.gz).has_extension("zip") == no
Path.is_directory
Path.is_directory : func(path: Path, follow_symlinks = yes -> Bool)
Checks if the path represents a directory. Optionally follows symbolic links.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to check. | - |
| follow_symlinks | `` | Whether to follow symbolic links. | yes |
Return: True if the path is a directory, False otherwise.
Example:
assert (./directory/).is_directory() == yes
assert (./file.txt).is_directory() == no
Path.is_file
Path.is_file : func(path: Path, follow_symlinks = yes -> Bool)
Checks if the path represents a file. Optionally follows symbolic links.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to check. | - |
| follow_symlinks | `` | Whether to follow symbolic links. | yes |
Return: True if the path is a file, False otherwise.
Example:
assert (./file.txt).is_file() == yes
assert (./directory/).is_file() == no
Path.is_socket
Path.is_socket : func(path: Path, follow_symlinks = yes -> Bool)
Checks if the path represents a socket. Optionally follows symbolic links.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to check. | - |
| follow_symlinks | `` | Whether to follow symbolic links. | yes |
Return: True if the path is a socket, False otherwise.
Example:
assert (./socket).is_socket() == yes
Path.is_symlink
Path.is_symlink : func(path: Path -> Bool)
Checks if the path represents a symbolic link.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to check. | - |
Return: True if the path is a symbolic link, False otherwise.
Example:
assert (./link).is_symlink() == yes
Path.lines
Path.lines : func(path: Path -> [Text]?)
Returns a list with the lines of text in a file or returns none if the file could not be opened.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file. | - |
Return: A list of the lines in a file or none if the file couldn't be read.
Example:
lines := (./file.txt).lines()!
Path.matches_glob
Path.matches_glob : func(path: Path, glob: Text -> Bool)
Return whether or not a path matches a given glob.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to check. | - |
| glob | Text |
The glob pattern to check. | - |
Return: Whether or not the path matches the given glob.
Example:
assert (./file.txt).matches_glob("*.txt")
assert (./file.c).matches_glob("*.{c,h}")
Path.modified
Path.modified : func(path: Path, follow_symlinks: Bool = yes -> Int64?)
Gets the file modification time of a file.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file whose modification time you want. | - |
| follow_symlinks | Bool |
Whether to follow symbolic links. | yes |
Return: A 64-bit unix epoch timestamp representing when the file or directory was last modified, or none if no such file or directory exists.
Example:
assert (./file.txt).modified() == Int64(1704221100)
assert (./not-a-file).modified() == none
Path.move
Path.move : func(path: Path, dest: Path, allow_overwriting = no -> Result)
Moves the file or directory from one location to another.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to move. | - |
| dest | Path |
The destination to move the path to. | - |
| allow_overwriting | `` | Whether to permit overwriting the destination if it is an existing file or directory. | no |
Return: Either Success or Failure(reason).
Example:
(./file.txt).move(/tmp/renamed.txt)!
Path.owner
Path.owner : func(path: Path, follow_symlinks: Bool = yes -> Text?)
Get the owning user of a file or directory.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path whose owner to get. | - |
| follow_symlinks | Bool |
Whether to follow symbolic links. | yes |
Return: The name of the user who owns the file or directory, or none if the path does not exist.
Example:
assert (/bin).owner() == "root"
assert (/non/existent/file).owner() == none
Path.parent
Path.parent : func(path: Path -> Path?)
Returns the parent directory of the file or directory at the specified path.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file or directory. | - |
Return: The path of the parent directory or none if the path is (/) (the file root).
Example:
assert (./path/to/file.txt).parent() == (./path/to/)
Path.read
Path.read : func(path: Path -> Text?)
Reads the contents of the file at the specified path or none if the file could not be read.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to read. | - |
Return: The contents of the file. If the file could not be read, none will be returned. If the file can be read, but is not valid UTF8 data, an error will be raised.
Example:
assert (./hello.txt).read() == "Hello"
assert (./nosuchfile.xxx).read() == none
Path.read_bytes
Path.read_bytes : func(path: Path, limit: Int? = none -> [Byte]?)
Reads the contents of the file at the specified path or none if the file could not be read.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to read. | - |
| limit | Int? |
A limit to how many bytes should be read. | none |
Return: The byte contents of the file. If the file cannot be read, none will be returned.
Example:
assert (./hello.txt).read_bytes()! == [72, 101, 108, 108, 111]
assert (./nosuchfile.xxx).read_bytes() == none
Path.relative_to
Path.relative_to : func(path: Path, relative_to = (./) -> Path)
Returns the path relative to a given base path. By default, the base path is the current directory.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to convert. | - |
| relative_to | `` | The base path for the relative path. | (./) |
Return: A relative path from the reference point to the given path.
Example:
assert (./path/to/file.txt).relative_to((./path)) == (./to/file.txt)
assert (/tmp/foo).relative_to((/tmp)) == (./foo)
Path.remove
Path.remove : func(path: Path, ignore_missing = no -> Result)
Removes the file or directory at the specified path. A runtime error is raised if something goes wrong.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to remove. | - |
| ignore_missing | `` | Whether to ignore errors if the file or directory does not exist. | no |
Return: Either Success or Failure(reason).
Example:
(./file.txt).remove()!
Path.resolved
Path.resolved : func(path: Path, relative_to = (./) -> Path)
Resolves the absolute path of the given path relative to a base path. By default, the base path is the current directory.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to resolve. | - |
| relative_to | `` | The base path for resolution. | (./) |
Return: The resolved absolute path.
Example:
assert (~/foo).resolved() == (/home/user/foo)
assert (./path/to/file.txt).resolved(relative_to=(/foo)) == (/foo/path/to/file.txt)
Path.set_owner
Path.set_owner : func(path: Path, owner: Text? = none, group: Text? = none, follow_symlinks: Bool = yes -> Result)
Set the owning user and/or group for a path.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to change the permissions for. | - |
| owner | Text? |
If non-none, the new user to assign to be the owner of the file. | none |
| group | Text? |
If non-none, the new group to assign to be the owner of the file. | none |
| follow_symlinks | Bool |
Whether to follow symbolic links. | yes |
Return: Either Success or Failure(reason).
Example:
(./file.txt).set_owner(owner="root", group="wheel")!
Path.sibling
Path.sibling : func(path: Path, name: Text -> Path)
Return a path that is a sibling of another path (i.e. has the same parent, but a different name). This is equivalent to .parent().child(name)
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
A path. | - |
| name | Text |
The name of a sibling file or directory. | - |
Return: A new path representing the sibling.
Example:
assert (/foo/baz).sibling("doop") == (/foo/doop)
Path.subdirectories
Path.subdirectories : func(path: Path, include_hidden = no -> [Path])
Returns a list of subdirectories within the directory at the specified path. Optionally includes hidden subdirectories.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the directory. | - |
| include_hidden | `` | Whether to include hidden subdirectories (those starting with a .) |
no |
Return: A list of subdirectory paths.
Example:
assert (./directory).subdirectories() == [(./directory/subdir1), (./directory/subdir2)]
assert (./directory).subdirectories(include_hidden=yes) == [(./directory/.git), (./directory/subdir1), (./directory/subdir2)]
Path.unique_directory
Path.unique_directory : func(path: Path -> Path)
Generates a unique directory path based on the given path. Useful for creating temporary directories.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The base path for generating the unique directory. The last six letters of this path must be XXXXXX. |
- |
Return: A unique directory path after creating the directory.
Example:
created := (/tmp/my-dir.XXXXXX).unique_directory()
assert created.is_directory() == yes
created.remove()!
Path.walk
Path.walk : func(path: Path, include_hidden = no, follow_symlinks: Bool = no -> func(->Path?))
Returns an iterator that efficiently recursively walks over every file and subdirectory in a given directory. The iteration order is not defined, but in practice it may look a lot like a breadth-first traversal.
The path itself is always included in the iteration.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path to begin the walk. | - |
| include_hidden | `` | Whether to include hidden files (those starting with a .) |
no |
| follow_symlinks | Bool |
Whether to follow symbolic links. Caution: if set to 'yes', it is possible for this iterator to get stuck in a loop, using increasingly large amounts of memory. | no |
Return: An iterator that recursively walks over every file and subdirectory.
Example:
for p in (/tmp).walk()
say("File or dir: $p")
# The path itself is always included:
assert [p for p in (./file.txt).walk()] == [(./file.txt)]
Path.write
Path.write : func(path: Path, text: Text, permissions = Int32(0o644) -> Result)
Writes the given text to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to write to. | - |
| text | Text |
The text to write to the file. | - |
| permissions | `` | The permissions to set on the file if it is created. | Int32(0o644) |
Return: Either Success or Failure(reason).
Example:
(./file.txt).write("Hello, world!")!
Path.write_bytes
Path.write_bytes : func(path: Path, bytes: [Byte], permissions = Int32(0o644) -> Result)
Writes the given bytes to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to write to. | - |
| bytes | [Byte] |
A list of bytes to write to the file. | - |
| permissions | `` | The permissions to set on the file if it is created. | Int32(0o644) |
Return: Either Success or Failure(reason).
Example:
(./file.txt).write_bytes([104, 105])!
Path.write_unique
Path.write_unique : func(path: Path, text: Text -> Path)
Writes the given text to a unique file path based on the specified path. The file is created if it doesn't exist. This is useful for creating temporary files.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The base path for generating the unique file. This path must include the string XXXXXX in the file base name. |
- |
| text | Text |
The text to write to the file. | - |
Return: The path of the newly created unique file.
Example:
created := (./file-XXXXXX.txt).write_unique("Hello, world!")!
assert created == (./file-27QHtq.txt)
assert created.read()! == "Hello, world!"
created.remove()!
Path.write_unique_bytes
Path.write_unique_bytes : func(path: Path, bytes: [Byte] -> Path)
Writes the given bytes to a unique file path based on the specified path. The file is created if it doesn't exist. This is useful for creating temporary files.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The base path for generating the unique file. This path must include the string XXXXXX in the file base name. |
- |
| bytes | [Byte] |
The bytes to write to the file. | - |
Return: The path of the newly created unique file.
Example:
created := (./file-XXXXXX.txt).write_unique_bytes([1, 2, 3])!
assert created == (./file-27QHtq.txt)
assert created.read_bytes()! == [1, 2, 3]
created.remove()!
Path.writer
Path.writer : func(path: Path, append: Bool = no, permissions: Int32 = Int32(0o644) -> func(text:Text, close:Bool=no -> Result))
Returns a function that can be used to repeatedly write to the same file.
The file writer will keep its file descriptor open after each write (unless the close argument is set to yes). If the file writer is never closed, it will be automatically closed when the file writer is garbage collected.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Path |
The path of the file to write to. | - |
| append | Bool |
If set to yes, writes to the file will append. If set to no, then the first write to the file will overwrite its contents and subsequent calls will append. |
no |
| permissions | Int32 |
The permissions to set on the file if it is created. | Int32(0o644) |
Return: Returns a function that can repeatedly write to the same file. If close is set to yes, then the file will be closed after writing. If this function is called again after closing, the file will be reopened for appending.
Example:
write := (./file.txt).writer()
write("Hello\n")!
write("world\n", close=yes)!
Table
Table.clear
Table.clear : func(t: &{K:V} -> Void)
Removes all key-value pairs from the table.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | &{K:V} |
The reference to the table. | - |
Return: Nothing.
Example:
t := &{"A":1}
t.clear()
assert t[] == {}
Table.difference
Table.difference : func(t: {K:V}, other: {K:V} -> {K:V})
Return a table whose key/value pairs correspond to keys only present in one table, but not the other.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The base table. | - |
| other | {K:V} |
The other table. | - |
Return: A table containing the common key/value pairs whose keys only appear in one table.
Example:
t1 := {"A": 1, "B": 2, "C": 3}
t2 := {"B": 2, "C":30, "D": 40}
assert t1.difference(t2) == {"A": 1, "D": 40}
Table.get
Table.get : func(t: {K:V}, key: K -> V?)
Retrieves the value associated with a key, or returns none if the key is not present.
Default values for the table are ignored.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The table. | - |
| key | K |
The key whose associated value is to be retrieved. | - |
Return: The value associated with the key or none if the key is not found.
Example:
t := {"A": 1, "B": 2}
assert t.get("A") == 1
assert t.get("????") == none
assert t.get("A")! == 1
assert t.get("????") or 0 == 0
Table.get_or_set
Table.get_or_set : func(t: &{K:V}, key: K, default: V -> V?)
If the given key is in the table, return the associated value. Otherwise, insert the given default value into the table and return it.
If no default value is provided explicitly, but the table has a default value associated with it, the table's default value will be used. The default value is only evaluated if the key is missing.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | &{K:V} |
The table. | - |
| key | K |
The key whose associated value is to be retrieved. | - |
| default | V |
The default value to insert and return if the key is not present in the table. | - |
Return: Either the value associated with the key (if present) or the default value. The table will be mutated if the key is not already present.
Example:
t := &{"A": @[1, 2, 3]; default=@[]}
t.get_or_set("A").insert(4)
t.get_or_set("B").insert(99)
assert t["A"][] == [1, 2, 3, 4]
assert t["B"][] == [99]
assert t.get_or_set("C", @[0, 0, 0])[] == [0, 0, 0]
Table.has
Table.has : func(t: {K:V}, key: K -> Bool)
Checks if the table contains a specified key.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The table. | - |
| key | K |
The key to check for presence. | - |
Return: yes if the key is present, no otherwise.
Example:
assert {"A": 1, "B": 2}.has("A") == yes
assert {"A": 1, "B": 2}.has("xxx") == no
Table.intersection
Table.intersection : func(t: {K:V}, other: {K:V} -> {K:V})
Return a table with only the matching key/value pairs that are common to both tables.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The base table. | - |
| other | {K:V} |
The other table. | - |
Return: A table containing the common key/value pairs shared between two tables.
Example:
t1 := {"A": 1, "B": 2, "C": 3}
t2 := {"B": 2, "C":30, "D": 40}
assert t1.intersection(t2) == {"B": 2}
Table.remove
Table.remove : func(t: {K:V}, key: K -> Void)
Removes the key-value pair associated with a specified key.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The reference to the table. | - |
| key | K |
The key of the key-value pair to remove. | - |
Return: Nothing.
Example:
t := &{"A": 1, "B": 2}
t.remove("A")
assert t == {"B": 2}
Table.set
Table.set : func(t: {K:V}, key: K, value: V -> Void)
Sets or updates the value associated with a specified key.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The reference to the table. | - |
| key | K |
The key to set or update. | - |
| value | V |
The value to associate with the key. | - |
Return: Nothing.
Example:
t := &{"A": 1, "B": 2}
t.set("C", 3)
assert t == {"A": 1, "B": 2, "C": 3}
Table.with
Table.with : func(t: {K:V}, other: {K:V} -> {K:V})
Return a copy of a table with values added from another table
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The base table. | - |
| other | {K:V} |
The other table from which new key/value pairs will be added. | - |
Return: The original table, but with values from the other table added.
Example:
t := {"A": 1, "B": 2}
assert t.with({"B": 20, "C": 30}) == {"A": 1, "B": 20, "C": 30}
Table.with_fallback
Table.with_fallback : func(t: {K:V}, fallback: {K:V}? -> {K:V})
Return a copy of a table with a different fallback table.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The table whose fallback will be replaced. | - |
| fallback | {K:V}? |
The new fallback table value. | - |
Return: The original table with a different fallback.
Example:
t := {"A": 1; fallback={"B": 2}}
t2 := t.with_fallback({"B": 3})
assert t2["B"] == 3
t3 := t.with_fallback(none)
assert t3["B"] == none
Table.without
Table.without : func(t: {K:V}, other: {K:V} -> {K:V})
Return a copy of a table, but without any of the exact key/value pairs found in the other table.
Only exact key/value pairs will be discarded. Keys with a non-matching value will be kept.
| Argument | Type | Description | Default |
|---|---|---|---|
| t | {K:V} |
The base table. | - |
| other | {K:V} |
The other table whose key/value pairs will be omitted. | - |
Return: The original table, but without the key/value pairs from the other table.
Example:
t := {"A": 1, "B": 2, "C": 3}
assert t.without({"B": 2, "C": 30, "D": 40}) == {"A": 1, "C": 3}
Text
Text.as_c_string
Text.as_c_string : func(text: Text -> CString)
Converts a Text value to a C-style string.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be converted to a C-style string. | - |
Return: A C-style string (CString) representing the text.
Example:
assert "Hello".as_c_string() == CString("Hello")
Text.at
Text.at : func(text: Text, index: Int -> Text)
Get the graphical cluster at a given index. This is similar to str[i] with ASCII text, but has more correct behavior for unicode text.
Negative indices are counted from the back of the text, so -1 means the last cluster, -2 means the second-to-last, and so on.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text from which to get a cluster. | - |
| index | Int |
The index of the graphical cluster (1-indexed). | - |
Return: A Text with the single graphical cluster at the given index.
Example:
assert "Amélie".at(3) == "é"
Text.by_line
Text.by_line : func(text: Text -> func(->Text?))
Returns an iterator function that can be used to iterate over the lines in a text.
This function ignores a trailing newline if there is one. If you don't want this behavior, use text.by_split($/{1 nl}/) instead.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be iterated over, line by line. | - |
Return: An iterator function that returns one line at a time, until it runs out and returns none.
Example:
text := "
line one
line two
"
lines := [line for line in text.by_line()]
assert lines == ["line one", "line two"]
Text.by_split
Text.by_split : func(text: Text, delimiter: Text = "" -> func(->Text?))
Returns an iterator function that can be used to iterate over text separated by a delimiter.
To split based on a set of delimiters, use Text.by_split_any(). If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be iterated over in delimited chunks. | - |
| delimiter | Text |
An exact delimiter to use for splitting the text. | "" |
Return: An iterator function that returns one chunk of text at a time, separated by the given delimiter, until it runs out and returns none.
Example:
text := "one,two,three"
chunks := [chunk for chunk in text.by_split(",")]
assert chunks == ["one", "two", "three"]
Text.by_split_any
Text.by_split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> func(->Text?))
Returns an iterator function that can be used to iterate over text separated by one or more characters (grapheme clusters) from a given text of delimiters.
Splitting will occur on every place where one or more of the grapheme clusters in delimiters occurs.
To split based on an exact delimiter, use Text.by_split().
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be iterated over in delimited chunks. | - |
| delimiters | Text |
Grapheme clusters to use for splitting the text. | " $\t\r\n" |
Return: An iterator function that returns one chunk of text at a time, separated by the given delimiter characters, until it runs out and returns none.
Example:
text := "one,two,;,three"
chunks := [chunk for chunk in text.by_split_any(",;")]
assert chunks == ["one", "two", "three"]
Text.caseless_equals
Text.caseless_equals : func(a: Text, b: Text, language: Text = "C" -> Bool)
Checks whether two texts are equal, ignoring the casing of the letters (i.e. case-insensitive comparison).
| Argument | Type | Description | Default |
|---|---|---|---|
| a | Text |
The first text to compare case-insensitively. | - |
| b | Text |
The second text to compare case-insensitively. | - |
| language | Text |
The ISO 639 language code for which casing rules to use. | "C" |
Return: yes if a and b are equal to each other, ignoring casing, otherwise no.
Example:
assert "A".caseless_equals("a") == yes
# Turkish lowercase "I" is "ı" (dotless I), not "i"
assert "I".caseless_equals("i", language="tr_TR") == no
Text.codepoint_names
Text.codepoint_names : func(text: Text -> [Text])
Returns a list of the names of each codepoint in the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text from which to extract codepoint names. | - |
Return: A list of codepoint names ([Text]).
Example:
assert "Amélie".codepoint_names() == [
"LATIN CAPITAL LETTER A",
"LATIN SMALL LETTER M",
"LATIN SMALL LETTER E WITH ACUTE",
"LATIN SMALL LETTER L",
"LATIN SMALL LETTER I",
"LATIN SMALL LETTER E",
]
Text.distance
Text.distance : func(a: Text, b: Text, language: Text = "C" -> Num)
Get an approximate distance between two texts, such that when the distance is small, the texts are similar and when the distance is large, the texts are dissimilar.
The exact distance algorithm is not specified and may be subject to change over time.
| Argument | Type | Description | Default |
|---|---|---|---|
| a | Text |
The first text to compare. | - |
| b | Text |
The second text to compare. | - |
| language | Text |
The ISO 639 language code for which character width to use. | "C" |
Return: The distance between the two texts (larger means more dissimilar).
Example:
assert "hello".distance("hello") == 0
texts := &["goodbye", "hello", "hallo"]
texts.sort(func(a,b:&Text) a.distance("hello") <> b.distance("hello"))
assert texts == ["hello", "hallo", "goodbye"]
Text.ends_with
Text.ends_with : func(text: Text, suffix: Text, remainder: &Text? = none -> Bool)
Checks if the Text ends with a literal suffix text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be searched. | - |
| suffix | Text |
The literal suffix text to check for. | - |
| remainder | &Text? |
If non-none, this value will be set to the rest of the text up to the trailing suffix. If the suffix is not found, this value will be set to the original text. | none |
Return: yes if the text has the target, no otherwise.
Example:
assert "hello world".ends_with("world") == yes
remainder : Text
assert "hello world".ends_with("world", &remainder) == yes
assert remainder == "hello "
Text.find
Text.find : func(text: Text, target: Text, start: Int = 1 -> Int)
Find a substring within a text and return its index, if found.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be searched. | - |
| target | Text |
The target text to find. | - |
| start | Int |
The index at which to begin searching. | 1 |
Return: The index where the first occurrence of target appears, or none if it is not found.
Example:
assert "one two".find("one") == 1
assert "one two".find("two") == 5
assert "one two".find("three") == none
assert "one two".find("o", start=2) == 7
Text.from
Text.from : func(text: Text, first: Int -> Text)
Get a slice of the text, starting at the given position.
A negative index counts backwards from the end of the text, so -1 refers to the last cluster, -2 the second-to-last, etc. Slice ranges will be truncated to the length of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be sliced. | - |
| first | Int |
The index to begin the slice. | - |
Return: The text from the given grapheme cluster to the end of the text.
Example:
assert "hello".from(2) == "ello"
assert "hello".from(-2) == "lo"
Text.from_c_string
Text.from_c_string : func(str: CString -> Text)
Converts a C-style string to a Text value.
| Argument | Type | Description | Default |
|---|---|---|---|
| str | CString |
The C-style string to be converted. | - |
Return: A Text value representing the C-style string.
Example:
assert Text.from_c_string(CString("Hello")) == "Hello"
Text.from_codepoint_names
Text.from_codepoint_names : func(codepoint_names: [Text] -> [Text])
Returns text that has the given codepoint names (according to the Unicode specification) as its codepoints.
The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.
| Argument | Type | Description | Default |
|---|---|---|---|
| codepoint_names | [Text] |
The names of each codepoint in the desired text (case-insentive). | - |
Return: A new text with the specified codepoints after normalization has been applied. Any invalid names are ignored.
Example:
text := Text.from_codepoint_names([
"LATIN CAPITAL LETTER A WITH RING ABOVE",
"LATIN SMALL LETTER K",
"LATIN SMALL LETTER E",
])
assert text == "Åke"
Text.from_utf16
Text.from_utf16 : func(bytes: [Int16] -> [Text])
Returns text that has been constructed from the given UTF16 sequence.
The text will be normalized, so the resulting text's UTF16 sequence may not exactly match the input.
| Argument | Type | Description | Default |
|---|---|---|---|
| bytes | [Int16] |
The UTF-16 integers of the desired text. | - |
Return: A new text based on the input UTF16 sequence after normalization has been applied.
Example:
assert Text.from_utf16([197, 107, 101]) == "Åke"
assert Text.from_utf16([12371, 12435, 12395, 12385, 12399, 19990, 30028]) == "こんにちは世界"
Text.from_utf32
Text.from_utf32 : func(codepoints: [Int32] -> [Text])
Returns text that has been constructed from the given UTF32 codepoints.
The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.
| Argument | Type | Description | Default |
|---|---|---|---|
| codepoints | [Int32] |
The UTF32 codepoints in the desired text. | - |
Return: A new text with the specified codepoints after normalization has been applied.
Example:
assert Text.from_utf32([197, 107, 101]) == "Åke"
Text.from_utf8
Text.from_utf8 : func(bytes: [Byte] -> [Text])
Returns text that has been constructed from the given UTF8 bytes.
The text will be normalized, so the resulting text's UTF8 bytes may not exactly match the input.
| Argument | Type | Description | Default |
|---|---|---|---|
| bytes | [Byte] |
The UTF-8 bytes of the desired text. | - |
Return: A new text based on the input UTF8 bytes after normalization has been applied.
Example:
assert Text.from_utf8([195, 133, 107, 101]) == "Åke"
Text.has
Text.has : func(text: Text, target: Text -> Bool)
Checks if the Text contains some target text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be searched. | - |
| target | Text |
The text to search for. | - |
Return: yes if the target text is found, no otherwise.
Example:
assert "hello world".has("wo") == yes
assert "hello world".has("xxx") == no
Text.join
Text.join : func(glue: Text, pieces: [Text] -> Text)
Joins a list of text pieces with a specified glue.
| Argument | Type | Description | Default |
|---|---|---|---|
| glue | Text |
The text used to join the pieces. | - |
| pieces | [Text] |
The list of text pieces to be joined. | - |
Return: A single Text value with the pieces joined by the glue.
Example:
assert ", ".join(["one", "two", "three"]) == "one, two, three"
Text.left_pad
Text.left_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)
Pad some text on the left side so it reaches a target width.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to pad. | - |
| width | Int |
The target width. | - |
| pad | Text |
The padding text. | " " |
| language | Text |
The ISO 639 language code for which character width to use. | "C" |
Return: Text with length at least width, with extra padding on the left as needed. If pad has length greater than 1, it may be partially repeated to reach the exact desired length.
Example:
assert "x".left_pad(5) == " x"
assert "x".left_pad(5, "ABC") == "ABCAx"
Text.lines
Text.lines : func(text: Text -> [Text])
Splits the text into a list of lines of text, preserving blank lines, ignoring trailing newlines, and handling \r\n the same as \n.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be split into lines. | - |
Return: A list of substrings resulting from the split.
Example:
assert "one\ntwo\nthree".lines() == ["one", "two", "three"]
assert "one\ntwo\nthree\n".lines() == ["one", "two", "three"]
assert "one\ntwo\nthree\n\n".lines() == ["one", "two", "three", ""]
assert "one\r\ntwo\r\nthree\r\n".lines() == ["one", "two", "three"]
assert "".lines() == []
Text.lower
Text.lower : func(text: Text, language: Text = "C" -> Text)
Converts all characters in the text to lowercase.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be converted to lowercase. | - |
| language | Text |
The ISO 639 language code for which casing rules to use. | "C" |
Return: The lowercase version of the text.
Example:
assert "AMÉLIE".lower() == "amélie"
assert "I".lower(language="tr_TR") == "ı"
Text.matches_glob
Text.matches_glob : func(path: Text, glob: Text -> Bool)
Return whether or not the text matches the given glob.
| Argument | Type | Description | Default |
|---|---|---|---|
| path | Text |
The text to check. | - |
| glob | Text |
The glob pattern to check. | - |
Return: Whether or not the text matches the given glob.
Example:
assert "hello world".matches_glob("h* *d")
Text.middle_pad
Text.middle_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)
Pad some text on the left and right side so it reaches a target width.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to pad. | - |
| width | Int |
The target width. | - |
| pad | Text |
The padding text. | " " |
| language | Text |
The ISO 639 language code for which character width to use. | "C" |
Return: Text with length at least width, with extra padding on the left and right as needed. If pad has length greater than 1, it may be partially repeated to reach the exact desired length.
Example:
assert "x".middle_pad(6) == " x "
assert "x".middle_pad(10, "ABC") == "ABCAxABCAB"
Text.quoted
Text.quoted : func(text: Text, color: Bool = no, quotation_mark: Text = `"` -> Text)
Formats the text with quotation marks and escapes.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be quoted. | - |
| color | Bool |
Whether to add color formatting. | no |
| quotation_mark | Text |
The quotation mark to use. | " |
Return: The text formatted as a quoted text.
Example:
assert "one\ntwo".quoted() == "\"one\\ntwo\""
Text.repeat
Text.repeat : func(text: Text, count: Int -> Text)
Repeat some text multiple times.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to repeat. | - |
| count | Int |
The number of times to repeat it. (Negative numbers are equivalent to zero). | - |
Return: The text repeated the given number of times.
Example:
assert "Abc".repeat(3) == "AbcAbcAbc"
Text.replace
Text.replace : func(text: Text, target: Text, replacement: Text -> Text)
Replaces occurrences of a target text with a replacement text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text in which to perform replacements. | - |
| target | Text |
The target text to be replaced. | - |
| replacement | Text |
The text to replace the target with. | - |
Return: The text with occurrences of the target replaced.
Example:
assert "Hello world".replace("world", "there") == "Hello there"
Text.reversed
Text.reversed : func(text: Text -> Text)
Return a text that has the grapheme clusters in reverse order.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to reverse. | - |
Return: A reversed version of the text.
Example:
assert "Abc".reversed() == "cbA"
Text.right_pad
Text.right_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)
Pad some text on the right side so it reaches a target width.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to pad. | - |
| width | Int |
The target width. | - |
| pad | Text |
The padding text. | " " |
| language | Text |
The ISO 639 language code for which character width to use. | "C" |
Return: Text with length at least width, with extra padding on the right as needed. If pad has length greater than 1, it may be partially repeated to reach the exact desired length.
Example:
assert "x".right_pad(5) == "x "
assert "x".right_pad(5, "ABC") == "xABCA"
Text.slice
Text.slice : func(text: Text, from: Int = 1, to: Int = -1 -> Text)
Get a slice of the text.
A negative index counts backwards from the end of the text, so -1 refers to the last cluster, -2 the second-to-last, etc. Slice ranges will be truncated to the length of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be sliced. | - |
| from | Int |
The index of the first grapheme cluster to include (1-indexed). | 1 |
| to | Int |
The index of the last grapheme cluster to include (1-indexed). | -1 |
Return: The text that spans the given grapheme cluster indices.
Example:
assert "hello".slice(2, 3) == "el"
assert "hello".slice(to=-2) == "hell"
assert "hello".slice(from=2) == "ello"
Text.split
Text.split : func(text: Text, delimiter: Text = "" -> [Text])
Splits the text into a list of substrings based on exact matches of a delimiter.
To split based on a set of delimiters, use Text.split_any(). If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be split. | - |
| delimiter | Text |
The delimiter used to split the text. | "" |
Return: A list of subtexts resulting from the split.
Example:
assert "one,two,,three".split(",") == ["one", "two", "", "three"]
assert "abc".split() == ["a", "b", "c"]
Text.split_any
Text.split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> [Text])
Splits the text into a list of substrings at one or more occurrences of a set of delimiter characters (grapheme clusters).
Splitting will occur on every place where one or more of the grapheme clusters in delimiters occurs.
To split based on an exact delimiter, use Text.split().
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be split. | - |
| delimiters | Text |
A text containing delimiters to use for splitting the text. | " $\t\r\n" |
Return: A list of subtexts resulting from the split.
Example:
assert "one, two,,three".split_any(", ") == ["one", "two", "three"]
Text.starts_with
Text.starts_with : func(text: Text, prefix: Text, remainder: &Text? = none -> Bool)
Checks if the Text starts with a literal prefix text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be searched. | - |
| prefix | Text |
The literal prefix text to check for. | - |
| remainder | &Text? |
If non-none, this value will be set to the rest of the text after the prefix. If the prefix is not found, this value will be set to the original text. | none |
Return: yes if the text has the given prefix, no otherwise.
Example:
assert "hello world".starts_with("hello") == yes
remainder : Text
assert "hello world".starts_with("hello", &remainder) == yes
assert remainder == " world"
Text.title
Text.title : func(text: Text, language: Text = "C" -> Text)
Converts the text to title case (capitalizing the first letter of each word).
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be converted to title case. | - |
| language | Text |
The ISO 639 language code for which casing rules to use. | "C" |
Return: The text in title case.
Example:
assert "amélie".title() == "Amélie"
# In Turkish, uppercase "i" is "İ"
assert "i".title(language="tr_TR") == "İ"
Text.to
Text.to : func(text: Text, last: Int -> Text)
Get a slice of the text, ending at the given position.
A negative index counts backwards from the end of the text, so -1 refers to the last cluster, -2 the second-to-last, etc. Slice ranges will be truncated to the length of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be sliced. | - |
| last | Int |
The index of the last grapheme cluster to include (1-indexed). | - |
Return: The text up to and including the given grapheme cluster.
Example:
assert "goodbye".to(3) == "goo"
assert "goodbye".to(-2) == "goodby"
Text.translate
Text.translate : func(text: Text, translations: {Text:Text} -> Text)
Takes a table mapping target texts to their replacements and performs all the replacements in the table on the whole text. At each position, the first matching replacement is applied and the matching moves on to after the replacement text, so replacement text is not recursively modified. See Text.replace() for more information about replacement behavior.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be translated. | - |
| translations | {Text:Text} |
A table mapping from target text to its replacement. | - |
Return: The text with all occurrences of the targets replaced with their corresponding replacement text.
Example:
text := "A <tag> & an ampersand".translate({
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
})
assert text == "A <tag> & an ampersand"
Text.trim
Text.trim : func(text: Text, to_trim: Text = " $\t\r\n", left: Bool = yes, right: Bool = yes -> Text)
Trims the given characters (grapheme clusters) from the left and/or right side of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be trimmed. | - |
| to_trim | Text |
The characters to remove from the left/right of the text. | " $\t\r\n" |
| left | Bool |
Whether or not to trim from the front of the text. | yes |
| right | Bool |
Whether or not to trim from the back of the text. | yes |
Return: The text without the trim characters at either end.
Example:
assert " x y z \n".trim() == "x y z"
assert "one,".trim(",") == "one"
assert " xyz ".trim(right=no) == "xyz "
Text.upper
Text.upper : func(text: Text, language: Text = "C" -> Text)
Converts all characters in the text to uppercase.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be converted to uppercase. | - |
| language | Text |
The ISO 639 language code for which casing rules to use. | "C" |
Return: The uppercase version of the text.
Example:
assert "amélie".upper() == "AMÉLIE"
# In Turkish, uppercase "i" is "İ"
assert "i".upper(language="tr_TR") == "İ"
Text.utf16
Text.utf16 : func(text: Text -> [Int16])
Returns a list of Unicode code points for UTF16 encoding of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text from which to extract Unicode code points. | - |
Return: A list of 16-bit integer Unicode code points ([Int16]).
Example:
assert "Åke".utf16() == [197, 107, 101]
assert "こんにちは世界".utf16() == [12371, 12435, 12395, 12385, 12399, 19990, 30028]
Text.utf32
Text.utf32 : func(text: Text -> [Int32])
Returns a list of Unicode code points for UTF32 encoding of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text from which to extract Unicode code points. | - |
Return: A list of 32-bit integer Unicode code points ([Int32]).
Example:
assert "Amélie".utf32() == [65, 109, 233, 108, 105, 101]
Text.utf8
Text.utf8 : func(text: Text -> [Byte])
Converts a Text value to a list of bytes representing a UTF8 encoding of the text.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to be converted to UTF8 bytes. | - |
Return: A list of bytes ([Byte]) representing the text in UTF8 encoding.
Example:
assert "Amélie".utf8() == [65, 109, 195, 169, 108, 105, 101]
Text.width
Text.width : func(text: Text -> Int)
Returns the display width of the text as seen in a terminal with appropriate font rendering. This is usually the same as the text's .length, but there are some characters like emojis that render wider than 1 cell.
This will not always be exactly accurate when your terminal's font rendering can't handle some unicode displaying correctly.
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text whose length you want. | - |
Return: An integer representing the display width of the text.
Example:
assert "Amélie".width() == 6
assert "🤠".width() == 2
Text.without_prefix
Text.without_prefix : func(text: Text, prefix: Text -> Text)
Returns the text with a given prefix removed (if present).
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to remove the prefix from. | - |
| prefix | Text |
The prefix to remove. | - |
Return: A text without the given prefix (if present) or the unmodified text if the prefix is not present.
Example:
assert "foo:baz".without_prefix("foo:") == "baz"
assert "qux".without_prefix("foo:") == "qux"
Text.without_suffix
Text.without_suffix : func(text: Text, suffix: Text -> Text)
Returns the text with a given suffix removed (if present).
| Argument | Type | Description | Default |
|---|---|---|---|
| text | Text |
The text to remove the suffix from. | - |
| suffix | Text |
The suffix to remove. | - |
Return: A text without the given suffix (if present) or the unmodified text if the suffix is not present.
Example:
assert "baz.foo".without_suffix(".foo") == "baz"
assert "qux".without_suffix(".foo") == "qux"
1 % API3 # Builtins4 ## USE_COLOR7 USE_COLOR : Bool8 ```10 Whether or not the console prefers ANSI color escape sequences in the output.12 ## ask15 ask : func(prompt: Text, bold: Bool = yes, force_tty: Bool = yes -> Text?)16 ```18 Gets a line of user input text with a prompt.20 When a program is receiving input from a pipe or writing its output to a pipe, this flag (which is enabled by default) forces the program to write the prompt to `/dev/tty` and read the input from `/dev/tty`, which circumvents the pipe. This means that `foo | ./tomo your-program | baz` will still show a visible prompt and read user input, despite the pipes. Setting this flag to `no` will mean that the prompt is written to `stdout` and input is read from `stdin`, even if those are pipes.22 Argument | Type | Description | Default23 ---------|------|-------------|---------28 **Return:** A line of user input text without a trailing newline, or empty text if something went wrong (e.g. the user hit `Ctrl-D`).31 **Example:**33 assert ask("What's your name? ") == "Arthur Dent"35 ```36 ## at_cleanup39 at_cleanup : func(fn: func() -> Void)40 ```42 Register a function that runs at cleanup time for Tomo programs. Cleanup time happens when a program exits (see `atexit()` in C), or immediately before printing error messages in a call to `fail()`. This allows for terminal cleanup so error messages can be visible as the program shuts down.44 Use this API very carefully, because errors that occur during cleanup functions may make it extremely hard to figure out what's going on. Cleanup functions should be designed to not error under any circumstances.46 Argument | Type | Description | Default47 ---------|------|-------------|---------53 **Example:**55 at_cleanup(func()56 _ := (/tmp/file.txt).remove(ignore_missing=yes)57 )59 ```60 ## exit63 exit : func(message: Text? = none, status: Int32 = Int32(1) -> Abort)64 ```66 Exits the program with a given status and optionally prints a message.68 Argument | Type | Description | Default69 ---------|------|-------------|---------70 message | `Text?` | If nonempty, this message will be printed (with a newline) before exiting. | `none`76 **Example:**78 exit("Goodbye forever!", Int32(1))80 ```81 ## fail84 fail : func(message: Text -> Abort)85 ```87 Prints a message to the console, aborts the program, and prints a stack trace.89 Argument | Type | Description | Default90 ---------|------|-------------|---------96 **Example:**98 fail("Oh no!")100 ```101 ## getenv104 getenv : func(name: Text -> Text?)105 ```107 Gets an environment variable.109 Argument | Type | Description | Default110 ---------|------|-------------|---------116 **Example:**118 assert getenv("TERM") == "xterm-256color"119 assert getenv("not_a_variable") == none121 ```122 ## print125 print : func(text: Text, newline: Bool = yes -> Void)126 ```128 Prints a message to the console (alias for say()).130 Argument | Type | Description | Default131 ---------|------|-------------|---------138 **Example:**140 print("Hello ", newline=no)141 print("world!")143 ```144 ## say147 say : func(text: Text, newline: Bool = yes -> Void)148 ```150 Prints a message to the console.152 Argument | Type | Description | Default153 ---------|------|-------------|---------160 **Example:**162 say("Hello ", newline=no)163 say("world!")165 ```166 ## setenv169 setenv : func(name: Text, value: Text? -> Void)170 ```172 Sets an environment variable.174 Argument | Type | Description | Default175 ---------|------|-------------|---------177 value | `Text?` | The new value of the environment variable. If `none`, then the environment variable will be unset. | -182 **Example:**184 setenv("FOOBAR", "xyz")186 ```187 ## sleep190 sleep : func(seconds: Num -> Void)191 ```193 Pause execution for a given number of seconds.195 Argument | Type | Description | Default196 ---------|------|-------------|---------202 **Example:**204 sleep(1.5)206 ```208 # Bool209 ## Bool.parse212 Bool.parse : func(text: Text, remainder: &Text? = none -> Bool?)213 ```215 Converts a text representation of a boolean value into a boolean. Acceptable boolean values are case-insensitive variations of `yes`/`no`, `y`/`n`, `true`/`false`, `on`/`off`.217 Argument | Type | Description | Default218 ---------|------|-------------|---------220 remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none`222 **Return:** `yes` if the string matches a recognized truthy boolean value; otherwise return `no`.225 **Example:**227 assert Bool.parse("yes") == yes228 assert Bool.parse("no") == no229 assert Bool.parse("???") == none231 assert Bool.parse("yesJUNK") == none232 remainder : Text233 assert Bool.parse("yesJUNK", &remainder) == yes234 assert remainder == "JUNK"236 ```238 # Byte239 ## Byte.get_bit242 Byte.get_bit : func(i: Byte, bit_index: Int -> Bool)243 ```245 In the binary representation of a byte, check whether a given bit index is set to 1 or not.247 The bit index must be between 1-8 or a runtime error will be produced.249 Argument | Type | Description | Default250 ---------|------|-------------|---------257 **Example:**259 assert Byte(6).get_bit(1) == no260 assert Byte(6).get_bit(2) == yes261 assert Byte(6).get_bit(3) == yes262 assert Byte(6).get_bit(4) == no264 ```265 ## Byte.hex268 Byte.hex : func(byte: Byte, uppercase: Bool = yes, prefix: Bool = no -> Text)269 ```271 Convert a byte to a hexidecimal text representation.273 Argument | Type | Description | Default274 ---------|------|-------------|---------282 **Example:**284 assert Byte(18).hex(prefix=yes) == "0x12"286 ```287 ## Byte.is_between290 Byte.is_between : func(x: Byte, low: Byte, high: Byte -> Bool)291 ```293 Determines if an integer is between two numbers (inclusive).295 Argument | Type | Description | Default296 ---------|------|-------------|---------304 **Example:**306 assert Byte(7).is_between(1, 10) == yes307 assert Byte(7).is_between(10, 1) == yes308 assert Byte(7).is_between(100, 200) == no309 assert Byte(7).is_between(1, 7) == yes311 ```312 ## Byte.parse315 Byte.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Byte?)316 ```318 Parse a byte literal from text.320 Argument | Type | Description | Default321 ---------|------|-------------|---------323 base | `Int?` | The numeric base to use when parsing the byte. If unspecified, the byte's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | `none`324 remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none`329 **Example:**331 assert Byte.parse("5") == Byte(5)332 assert Byte.parse("asdf") == none333 assert Byte.parse("123xyz") == none335 remainder : Text336 assert Byte.parse("123xyz", remainder=&remainder) == Byte(123)337 assert remainder == "xyz"339 ```340 ## Byte.to343 Byte.to : func(first: Byte, last: Byte, step: Int8? = none -> func(->Byte?))344 ```346 Returns an iterator function that iterates over the range of bytes specified.348 Argument | Type | Description | Default349 ---------|------|-------------|---------352 step | `Int8?` | An optional step size to use. If unspecified or `none`, the step will be inferred to be `+1` if `last >= first`, otherwise `-1`. | `none`357 **Example:**359 iter := Byte(2).to(4)360 assert iter() == Byte(2)361 assert iter() == Byte(3)362 assert iter() == Byte(4)363 assert iter() == none365 assert [x for x in Byte(2).to(5)] == [Byte(2), Byte(3), Byte(4), Byte(5)]366 assert [x for x in Byte(5).to(2)] == [Byte(5), Byte(4), Byte(3), Byte(2)]367 assert [x for x in Byte(2).to(5, step=2)] == [Byte(2), Byte(4)]369 ```371 # CString372 ## CString.as_text375 CString.as_text : func(str: CString -> Text)376 ```378 Convert a C string to Text.380 Argument | Type | Description | Default381 ---------|------|-------------|---------387 **Example:**389 assert CString("Hello").as_text() == "Hello"391 ```392 ## CString.join395 CString.join : func(glue: CString, pieces: [CString] -> CString)396 ```398 Join a list of C strings together with a separator.400 Argument | Type | Description | Default401 ---------|------|-------------|---------408 **Example:**410 assert CString(",").join([CString("a"), CString("b")]) == CString("a,b")412 ```414 # Int415 ## Int.abs418 Int.abs : func(x: Int -> Int)419 ```421 Calculates the absolute value of an integer.423 Argument | Type | Description | Default424 ---------|------|-------------|---------430 **Example:**432 assert (-10).abs() == 10434 ```435 ## Int.choose438 Int.choose : func(n: Int, k: Int -> Int)439 ```441 Computes the binomial coefficient of the given numbers (the equivalent of `n` choose `k` in combinatorics). This is equal to `n.factorial()/(k.factorial() * (n-k).factorial())`.443 Argument | Type | Description | Default444 ---------|------|-------------|---------448 **Return:** The binomial coefficient, equivalent to the number of ways to uniquely choose `k` objects from among `n` objects, ignoring order.451 **Example:**453 assert 4.choose(2) == 6455 ```456 ## Int.clamped459 Int.clamped : func(x: Int, low: Int, high: Int -> Int)460 ```462 Returns the given number clamped between two values so that it is within that range.464 Argument | Type | Description | Default465 ---------|------|-------------|---------473 **Example:**475 assert 2.clamped(5, 10) == 5477 ```478 ## Int.factorial481 Int.factorial : func(n: Int -> Text)482 ```484 Computes the factorial of an integer.486 Argument | Type | Description | Default487 ---------|------|-------------|---------493 **Example:**495 assert 10.factorial() == 3628800497 ```498 ## Int.get_bit501 Int.get_bit : func(i: Int, bit_index: Int -> Bool)502 ```504 In the binary representation of an integer, check whether a given bit index is set to 1 or not.506 For fixed-size integers, the bit index must be between 1 and the number of bits in that integer (i.e. 1-64 for `Int64`). For `Int`, the bit index must be between 1 and `Int64.max`. Values outside this range will produce a runtime error.508 Argument | Type | Description | Default509 ---------|------|-------------|---------513 **Return:** Whether or not the given bit index is set to 1 in the binary representation of the integer.516 **Example:**518 assert 6.get_bit(1) == no519 assert 6.get_bit(2) == yes520 assert 6.get_bit(3) == yes521 assert 6.get_bit(4) == no523 ```524 ## Int.hex527 Int.hex : func(i: Int, digits: Int = 0, uppercase: Bool = yes, prefix: Bool = yes -> Text)528 ```530 Converts an integer to its hexadecimal representation.532 Argument | Type | Description | Default533 ---------|------|-------------|---------542 **Example:**544 assert 255.hex(digits=4, uppercase=yes, prefix=yes) == "0x00FF"546 ```547 ## Int.is_between550 Int.is_between : func(x: Int, a: Int, b: Int -> Bool)551 ```553 Determines if an integer is between two numbers (inclusive).555 Argument | Type | Description | Default556 ---------|------|-------------|---------564 **Example:**566 assert 7.is_between(1, 10) == yes567 assert 7.is_between(10, 1) == yes568 assert 7.is_between(100, 200) == no569 assert 7.is_between(1, 7) == yes571 ```572 ## Int.is_prime575 Int.is_prime : func(x: Int, reps: Int = 50 -> Bool)576 ```578 Determines if an integer is a prime number.580 This function is _probabilistic_. With the default arguments, the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details.582 Argument | Type | Description | Default583 ---------|------|-------------|---------590 **Example:**592 assert 7.is_prime() == yes593 assert 6.is_prime() == no595 ```596 ## Int.next_prime599 Int.next_prime : func(x: Int -> Int)600 ```602 Finds the next prime number greater than the given integer.604 This function is _probabilistic_, but the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details.606 Argument | Type | Description | Default607 ---------|------|-------------|---------613 **Example:**615 assert 11.next_prime() == 13617 ```618 ## Int.octal621 Int.octal : func(i: Int, digits: Int = 0, prefix: Bool = yes -> Text)622 ```624 Converts an integer to its octal representation.626 Argument | Type | Description | Default627 ---------|------|-------------|---------635 **Example:**637 assert 64.octal(digits=4, prefix=yes) == "0o0100"639 ```640 ## Int.onward643 Int.onward : func(first: Int, step: Int = 1 -> Text)644 ```646 Return an iterator that counts infinitely from the starting integer (with an optional step size).648 Argument | Type | Description | Default649 ---------|------|-------------|---------656 **Example:**658 nums : &[Int] = &[]659 for i in 5.onward()660 nums.insert(i)661 stop if i == 10662 assert nums[] == [5, 6, 7, 8, 9, 10]664 ```665 ## Int.parse668 Int.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Int?)669 ```671 Converts a text representation of an integer into an integer.673 Argument | Type | Description | Default674 ---------|------|-------------|---------676 base | `Int?` | The numeric base to use when parsing the integer. If unspecified, the integer's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | `none`677 remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none`679 **Return:** The integer represented by the text. If the given text contains a value outside of the representable range or if the entire text can't be parsed as an integer, `none` will be returned.682 **Example:**684 assert Int.parse("123") == 123685 assert Int.parse("0xFF") == 255686 assert Int.parse("123xyz") == none687 remainder : Text688 assert Int.parse("123xyz", remainder=&remainder) == 123689 assert remainder == "xyz"691 # Can't parse:692 assert Int.parse("asdf") == none694 # Outside valid range:695 assert Int8.parse("9999999") == none697 # Explicitly specifying base:698 assert Int.parse("10", base=16) == 16700 ```701 ## Int.sqrt704 Int.sqrt : func(x: Int -> Int)705 ```707 Calculates the nearest square root of an integer.709 Argument | Type | Description | Default710 ---------|------|-------------|---------716 **Example:**718 assert 16.sqrt() == 4719 assert 17.sqrt() == 4721 ```722 ## Int.to725 Int.to : func(first: Int, last: Int, step: Int? = none -> func(->Int?))726 ```728 Returns an iterator function that iterates over the range of numbers specified.730 Argument | Type | Description | Default731 ---------|------|-------------|---------734 step | `Int?` | An optional step size to use. If unspecified or `none`, the step will be inferred to be `+1` if `last >= first`, otherwise `-1`. | `none`739 **Example:**741 iter := 2.to(5)742 assert iter() == 2743 assert iter() == 3744 assert iter() == 4745 assert iter() == 5746 assert iter() == none748 assert [x for x in 2.to(5)] == [2, 3, 4, 5]749 assert [x for x in 5.to(2)] == [5, 4, 3, 2]750 assert [x for x in 2.to(5, step=2)] == [2, 4]752 ```754 # List755 ## List.binary_search758 List.binary_search : func(list: [T], by: func(x,y:&T->Int32) = T.compare -> Int)759 ```761 Performs a binary search on a sorted list.763 Argument | Type | Description | Default764 ---------|------|-------------|---------766 by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare`768 **Return:** Assuming the input list is sorted according to the given comparison function, return the index where the given item would be inserted to maintain the sorted order. That is, if the item is found, return its index, otherwise return the place where it would be found if it were inserted and the list were sorted.771 **Example:**773 assert [1, 3, 5, 7, 9].binary_search(5) == 3774 assert [1, 3, 5, 7, 9].binary_search(-999) == 1775 assert [1, 3, 5, 7, 9].binary_search(999) == 6777 ```778 ## List.by781 List.by : func(list: [T], step: Int -> [T])782 ```784 Creates a new list with elements spaced by the specified step value.786 Argument | Type | Description | Default787 ---------|------|-------------|---------794 **Example:**796 assert [1, 2, 3, 4, 5, 6].by(2) == [1, 3, 5]798 ```799 ## List.clear802 List.clear : func(list: @[T] -> Void)803 ```805 Clears all elements from the list.807 Argument | Type | Description | Default808 ---------|------|-------------|---------814 **Example:**816 list := &[10, 20]817 list.clear()818 assert list[] == []820 ```821 ## List.counts824 List.counts : func(list: [T] -> {T=Int})825 ```827 Counts the occurrences of each element in the list.829 Argument | Type | Description | Default830 ---------|------|-------------|---------836 **Example:**838 assert [10, 20, 30, 30, 30].counts() == {10:1, 20:1, 30:3}840 ```841 ## List.find844 List.find : func(list: [T], target: T -> Int?)845 ```847 Finds the index of the first occurrence of an element (if any).849 Argument | Type | Description | Default850 ---------|------|-------------|---------857 **Example:**859 assert [10, 20, 30, 40, 50].find(20) == 2860 assert [10, 20, 30, 40, 50].find(9999) == none862 ```863 ## List.from866 List.from : func(list: [T], first: Int -> [T])867 ```869 Returns a slice of the list starting from a specified index.871 Argument | Type | Description | Default872 ---------|------|-------------|---------879 **Example:**881 assert [10, 20, 30, 40, 50].from(3) == [30, 40, 50]883 ```884 ## List.has887 List.has : func(list: [T], target: T -> Bool)888 ```890 Checks if the list has an element.892 Argument | Type | Description | Default893 ---------|------|-------------|---------900 **Example:**902 assert [10, 20, 30].has(20) == yes904 ```905 ## List.heap_pop908 List.heap_pop : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> T?)909 ```911 Removes and returns the top element of a heap or `none` if the list is empty. By default, this is the *minimum* value in the heap.913 Argument | Type | Description | Default914 ---------|------|-------------|---------916 by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare`921 **Example:**923 my_heap := &[30, 10, 20]924 my_heap.heapify()925 assert my_heap.heap_pop() == 10927 ```928 ## List.heap_push931 List.heap_push : func(list: @[T], item: T, by = T.compare -> Void)932 ```934 Adds an element to the heap and maintains the heap property. By default, this is a *minimum* heap.936 Argument | Type | Description | Default937 ---------|------|-------------|---------940 by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare`945 **Example:**947 my_heap : &[Int]948 my_heap.heap_push(10)949 assert my_heap.heap_pop() == 10951 ```952 ## List.heapify955 List.heapify : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> Void)956 ```958 Converts a list into a heap.960 Argument | Type | Description | Default961 ---------|------|-------------|---------963 by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare`968 **Example:**970 my_heap := &[30, 10, 20]971 my_heap.heapify()973 ```974 ## List.insert977 List.insert : func(list: @[T], item: T, at: Int = 0 -> Void)978 ```980 Inserts an element at a specified position in the list.982 Since indices are 1-indexed and negative indices mean "starting from the back", an index of `0` means "after the last item".984 Argument | Type | Description | Default985 ---------|------|-------------|---------993 **Example:**995 list := &[10, 20]996 list.insert(30)997 assert list == [10, 20, 30]999 list.insert(999, at=2)1000 assert list == [10, 999, 20, 30]1002 ```1003 ## List.insert_all1006 List.insert_all : func(list: @[T], items: [T], at: Int = 0 -> Void)1007 ```1009 Inserts a list of items at a specified position in the list.1011 Since indices are 1-indexed and negative indices mean "starting from the back", an index of `0` means "after the last item".1013 Argument | Type | Description | Default1014 ---------|------|-------------|---------1022 **Example:**1024 list := &[10, 20]1025 list.insert_all([30, 40])1026 assert list == [10, 20, 30, 40]1028 list.insert_all([99, 100], at=2)1029 assert list == [10, 99, 100, 20, 30, 40]1031 ```1032 ## List.pop1035 List.pop : func(list: &[T], index: Int = -1 -> T?)1036 ```1038 Removes and returns an item from the list. If the given index is present in the list, the item at that index will be removed and the list will become one element shorter.1040 Since negative indices are counted from the back, the default behavior is to pop the last value.1042 Argument | Type | Description | Default1043 ---------|------|-------------|---------1047 **Return:** `none` if the list is empty or the given index does not exist in the list, otherwise the item at the given index.1050 **Example:**1052 list := &[10, 20, 30, 40]1054 assert list.pop() == 401055 assert list[] == [10, 20, 30]1057 assert list.pop(index=2) == 201058 assert list[] == [10, 30]1060 ```1061 ## List.random1064 List.random : func(list: [T], random: func(min,max:Int64->Int64)? = none -> T?)1065 ```1067 Selects a random element from the list.1069 Argument | Type | Description | Default1070 ---------|------|-------------|---------1072 random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none`1077 **Example:**1079 nums := [10, 20, 30]1080 pick := nums.random()!1081 assert nums.has(pick)1082 empty : [Int]1083 assert empty.random() == none1085 ```1086 ## List.remove_at1089 List.remove_at : func(list: @[T], at: Int = -1, count: Int = 1 -> Void)1090 ```1092 Removes elements from the list starting at a specified index.1094 Since negative indices are counted from the back, the default behavior is to remove the last item.1096 Argument | Type | Description | Default1097 ---------|------|-------------|---------1105 **Example:**1107 list := &[10, 20, 30, 40, 50]1108 list.remove_at(2)1109 assert list == [10, 30, 40, 50]1111 list.remove_at(2, count=2)1112 assert list == [10, 50]1114 ```1115 ## List.remove_item1118 List.remove_item : func(list: @[T], item: T, max_count: Int = -1 -> Void)1119 ```1121 Removes all occurrences of a specified item from the list.1125 Argument | Type | Description | Default1126 ---------|------|-------------|---------1134 **Example:**1136 list := &[10, 20, 10, 20, 30]1137 list.remove_item(10)1138 assert list == [20, 20, 30]1140 list.remove_item(20, max_count=1)1141 assert list == [20, 30]1143 ```1144 ## List.reversed1147 List.reversed : func(list: [T] -> [T])1148 ```1150 Returns a reversed slice of the list.1152 Argument | Type | Description | Default1153 ---------|------|-------------|---------1159 **Example:**1161 assert [10, 20, 30].reversed() == [30, 20, 10]1163 ```1164 ## List.sample1167 List.sample : func(list: [T], count: Int, weights: [Num]? = none, random: func(->Num)? = none -> [T])1168 ```1170 Selects a sample of elements from the list, optionally with weighted probabilities.1172 Errors will be raised if any of the following conditions occurs: - The given list has no elements and `count >= 1` - `count < 0` (negative count) - The number of weights provided doesn't match the length of the list. - Any weight in the weights list is negative, infinite, or `NaN` - The sum of the given weights is zero (zero probability for every element).1174 Argument | Type | Description | Default1175 ---------|------|-------------|---------1178 weights | `[Num]?` | The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. | `none`1179 random | `func(->Num)?` | If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between `0.0` (inclusive) and `1.0` (exclusive). (Used for deterministic pseudorandom number generation) | `none`1184 **Example:**1186 _ := [10, 20, 30].sample(2, weights=[90%, 5%, 5%]) # E.g. [10, 10]1188 ```1189 ## List.shuffle1192 List.shuffle : func(list: @[T], random: func(min,max:Int64->Int64)? = none -> Void)1193 ```1195 Shuffles the elements of the list in place.1197 Argument | Type | Description | Default1198 ---------|------|-------------|---------1200 random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none`1205 **Example:**1207 nums := &[10, 20, 30, 40]1208 nums.shuffle()1209 # E.g. [20, 40, 10, 30]1211 ```1212 ## List.shuffled1215 List.shuffled : func(list: [T], random: func(min,max:Int64->Int64)? = none -> [T])1216 ```1218 Creates a new list with elements shuffled.1220 Argument | Type | Description | Default1221 ---------|------|-------------|---------1223 random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none`1228 **Example:**1230 nums := [10, 20, 30, 40]1231 _ := nums.shuffled()1232 # E.g. [20, 40, 10, 30]1234 ```1235 ## List.slice1238 List.slice : func(list: [T], from: Int, to: Int -> [T])1239 ```1241 Returns a slice of the list spanning the given indices (inclusive).1243 Argument | Type | Description | Default1244 ---------|------|-------------|---------1249 **Return:** A new list spanning the given indices. Note: negative indices are counted from the back of the list, so `-1` refers to the last element, `-2` the second-to-last, and so on.1252 **Example:**1254 assert [10, 20, 30, 40, 50].slice(2, 4) == [20, 30, 40]1255 assert [10, 20, 30, 40, 50].slice(-3, -2) == [30, 40]1257 ```1258 ## List.sort1261 List.sort : func(list: @[T], by = T.compare -> Void)1262 ```1264 Sorts the elements of the list in place in ascending order (small to large).1266 Argument | Type | Description | Default1267 ---------|------|-------------|---------1269 by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare`1274 **Example:**1276 list := &[40, 10, -30, 20]1277 list.sort()1278 assert list == [-30, 10, 20, 40]1280 list.sort(func(a,b:&Int) a.abs() <> b.abs())1281 assert list == [10, 20, -30, 40]1283 ```1284 ## List.sorted1287 List.sorted : func(list: [T], by = T.compare -> [T])1288 ```1290 Creates a new list with elements sorted.1292 Argument | Type | Description | Default1293 ---------|------|-------------|---------1295 by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare`1300 **Example:**1302 assert [40, 10, -30, 20].sorted() == [-30, 10, 20, 40]1303 assert [40, 10, -30, 20].sorted(1304 func(a,b:&Int) a.abs() <> b.abs()1305 ) == [10, 20, -30, 40]1307 ```1308 ## List.to1311 List.to : func(list: [T], last: Int -> [T])1312 ```1314 Returns a slice of the list from the start of the original list up to a specified index (inclusive).1316 Argument | Type | Description | Default1317 ---------|------|-------------|---------1324 **Example:**1326 assert [10, 20, 30, 40, 50].to(3) == [10, 20, 30]1327 assert [10, 20, 30, 40, 50].to(-2) == [10, 20, 30, 40]1329 ```1330 ## List.unique1333 List.unique : func(list: [T] -> {T})1334 ```1336 Returns a set of the unique elements of the list.1338 Argument | Type | Description | Default1339 ---------|------|-------------|---------1345 **Example:**1347 assert [10, 20, 10, 10, 30].unique() == {10, 20, 30}1349 ```1350 ## List.where1353 List.where : func(list: [T], predicate: func(item:&T -> Bool) -> Int)1354 ```1356 Find the index of the first item that matches a predicate function (if any).1358 Argument | Type | Description | Default1359 ---------|------|-------------|---------1361 predicate | `func(item:&T -> Bool)` | A function that returns `yes` if the item's index should be returned or `no` if it should not. | -1363 **Return:** Returns the index of the first item where the predicate is true or `none` if no item matches.1366 **Example:**1368 assert ["BC", "ABC", "CD"].where(func(t:&Text) t.starts_with("A")) == 21369 assert ["BC", "ABC", "CD"].where(func(t:&Text) t.starts_with("X")) == none1371 ```1373 # Num1374 ## Num.1_PI1377 Num.1_PI : Num1378 ```1380 The constant $\frac{1}{\pi}$.1382 ## Num.2_PI1385 Num.2_PI : Num1386 ```1388 The constant $2 \times \pi$.1390 ## Num.2_SQRTPI1393 Num.2_SQRTPI : Num1394 ```1396 The constant $2 \times \sqrt{\pi}$.1398 ## Num.E1401 Num.E : Num1402 ```1404 The base of the natural logarithm ($e$).1406 ## Num.INF1409 Num.INF : Num1410 ```1412 Positive infinity.1414 ## Num.LN101417 Num.LN10 : Num1418 ```1420 The natural logarithm of 10.1422 ## Num.LN21425 Num.LN2 : Num1426 ```1428 The natural logarithm of 2.1430 ## Num.LOG2E1433 Num.LOG2E : Num1434 ```1436 The base 2 logarithm of $e$1438 ## Num.PI1441 Num.PI : Num1442 ```1444 Pi ($\pi$).1446 ## Num.PI_21449 Num.PI_2 : Num1450 ```1452 $\frac{\pi}{2}$1454 ## Num.PI_41457 Num.PI_4 : Num1458 ```1460 $\frac{\pi}{4}$1462 ## Num.SQRT1_21465 Num.SQRT1_2 : Num1466 ```1468 $\sqrt{\frac{1}{2}}$1470 ## Num.SQRT21473 Num.SQRT2 : Num1474 ```1476 $\sqrt{2}$1478 ## Num.TAU1481 Num.TAU : Num1482 ```1484 Tau ($2 \times \pi$)1486 ## Num.abs1489 Num.abs : func(n: Num -> Num)1490 ```1492 Calculates the absolute value of a number.1494 Argument | Type | Description | Default1495 ---------|------|-------------|---------1501 **Example:**1503 assert (-3.5).abs() == 3.51505 ```1506 ## Num.acos1509 Num.acos : func(x: Num -> Num)1510 ```1512 Computes the arc cosine of a number.1514 Argument | Type | Description | Default1515 ---------|------|-------------|---------1521 **Example:**1523 assert (0.0).acos().near(1.5707963267948966)1525 ```1526 ## Num.acosh1529 Num.acosh : func(x: Num -> Num)1530 ```1532 Computes the inverse hyperbolic cosine of a number.1534 Argument | Type | Description | Default1535 ---------|------|-------------|---------1541 **Example:**1543 assert (1.0).acosh() == 01545 ```1546 ## Num.asin1549 Num.asin : func(x: Num -> Num)1550 ```1552 Computes the arc sine of a number.1554 Argument | Type | Description | Default1555 ---------|------|-------------|---------1561 **Example:**1563 assert (0.5).asin().near(0.5235987755982989)1565 ```1566 ## Num.asinh1569 Num.asinh : func(x: Num -> Num)1570 ```1572 Computes the inverse hyperbolic sine of a number.1574 Argument | Type | Description | Default1575 ---------|------|-------------|---------1581 **Example:**1583 assert (0.0).asinh() == 01585 ```1586 ## Num.atan1589 Num.atan : func(x: Num -> Num)1590 ```1592 Computes the arc tangent of a number.1594 Argument | Type | Description | Default1595 ---------|------|-------------|---------1601 **Example:**1603 assert (1.0).atan().near(0.7853981633974483)1605 ```1606 ## Num.atan21609 Num.atan2 : func(x: Num, y: Num -> Num)1610 ```1612 Computes the arc tangent of the quotient of two numbers.1614 Argument | Type | Description | Default1615 ---------|------|-------------|---------1622 **Example:**1624 assert Num.atan2(1, 1).near(0.7853981633974483)1626 ```1627 ## Num.atanh1630 Num.atanh : func(x: Num -> Num)1631 ```1633 Computes the inverse hyperbolic tangent of a number.1635 Argument | Type | Description | Default1636 ---------|------|-------------|---------1642 **Example:**1644 assert (0.5).atanh().near(0.5493061443340549)1646 ```1647 ## Num.cbrt1650 Num.cbrt : func(x: Num -> Num)1651 ```1653 Computes the cube root of a number.1655 Argument | Type | Description | Default1656 ---------|------|-------------|---------1662 **Example:**1664 assert (27.0).cbrt() == 31666 ```1667 ## Num.ceil1670 Num.ceil : func(x: Num -> Num)1671 ```1673 Rounds a number up to the nearest integer.1675 Argument | Type | Description | Default1676 ---------|------|-------------|---------1682 **Example:**1684 assert (3.2).ceil() == 41686 ```1687 ## Num.clamped1690 Num.clamped : func(x: Num, low: Num, high: Num -> Num)1691 ```1693 Returns the given number clamped between two values so that it is within that range.1695 Argument | Type | Description | Default1696 ---------|------|-------------|---------1704 **Example:**1706 assert (2.5).clamped(5.5, 10.5) == 5.51708 ```1709 ## Num.copysign1712 Num.copysign : func(x: Num, y: Num -> Num)1713 ```1715 Copies the sign of one number to another.1717 Argument | Type | Description | Default1718 ---------|------|-------------|---------1725 **Example:**1727 assert (3.0).copysign(-1) == -31729 ```1730 ## Num.cos1733 Num.cos : func(x: Num -> Num)1734 ```1736 Computes the cosine of a number (angle in radians).1738 Argument | Type | Description | Default1739 ---------|------|-------------|---------1745 **Example:**1747 assert (0.0).cos() == 11749 ```1750 ## Num.cosh1753 Num.cosh : func(x: Num -> Num)1754 ```1756 Computes the hyperbolic cosine of a number.1758 Argument | Type | Description | Default1759 ---------|------|-------------|---------1765 **Example:**1767 assert (0.0).cosh() == 11769 ```1770 ## Num.erf1773 Num.erf : func(x: Num -> Num)1774 ```1776 Computes the error function of a number.1778 Argument | Type | Description | Default1779 ---------|------|-------------|---------1785 **Example:**1787 assert (0.0).erf() == 01789 ```1790 ## Num.erfc1793 Num.erfc : func(x: Num -> Num)1794 ```1796 Computes the complementary error function of a number.1798 Argument | Type | Description | Default1799 ---------|------|-------------|---------1805 **Example:**1807 assert (0.0).erfc() == 11809 ```1810 ## Num.exp1813 Num.exp : func(x: Num -> Num)1814 ```1816 Computes the exponential function $e^x$ for a number.1818 Argument | Type | Description | Default1819 ---------|------|-------------|---------1825 **Example:**1827 assert (1.0).exp().near(2.718281828459045)1829 ```1830 ## Num.exp21833 Num.exp2 : func(x: Num -> Num)1834 ```1836 Computes $2^x$ for a number.1838 Argument | Type | Description | Default1839 ---------|------|-------------|---------1845 **Example:**1847 assert (3.0).exp2() == 81849 ```1850 ## Num.expm11853 Num.expm1 : func(x: Num -> Num)1854 ```1856 Computes $e^x - 1$ for a number.1858 Argument | Type | Description | Default1859 ---------|------|-------------|---------1865 **Example:**1867 assert (1.0).expm1().near(1.7182818284590453)1869 ```1870 ## Num.fdim1873 Num.fdim : func(x: Num, y: Num -> Num)1874 ```1876 Computes the positive difference between two numbers.1878 Argument | Type | Description | Default1879 ---------|------|-------------|---------1886 **Example:**1888 assert (5.0).fdim(3) == 21890 ```1891 ## Num.floor1894 Num.floor : func(x: Num -> Num)1895 ```1897 Rounds a number down to the nearest integer.1899 Argument | Type | Description | Default1900 ---------|------|-------------|---------1906 **Example:**1908 assert (3.7).floor() == 31910 ```1911 ## Num.hypot1914 Num.hypot : func(x: Num, y: Num -> Num)1915 ```1917 Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers.1919 Argument | Type | Description | Default1920 ---------|------|-------------|---------1927 **Example:**1929 assert Num.hypot(3, 4) == 51931 ```1932 ## Num.is_between1935 Num.is_between : func(x: Num, low: Num, high: Num -> Bool)1936 ```1938 Determines if a number is between two numbers (inclusive).1940 Argument | Type | Description | Default1941 ---------|------|-------------|---------1949 **Example:**1951 assert (7.5).is_between(1, 10) == yes1952 assert (7.5).is_between(10, 1) == yes1953 assert (7.5).is_between(100, 200) == no1954 assert (7.5).is_between(1, 7.5) == yes1956 ```1957 ## Num.isfinite1960 Num.isfinite : func(n: Num -> Bool)1961 ```1963 Checks if a number is finite.1965 Argument | Type | Description | Default1966 ---------|------|-------------|---------1972 **Example:**1974 assert (1.0).isfinite() == yes1975 assert Num.INF.isfinite() == no1977 ```1978 ## Num.isinf1981 Num.isinf : func(n: Num -> Bool)1982 ```1984 Checks if a number is infinite.1986 Argument | Type | Description | Default1987 ---------|------|-------------|---------1993 **Example:**1995 assert Num.INF.isinf() == yes1996 assert (1.0).isinf() == no1998 ```1999 ## Num.j02002 Num.j0 : func(x: Num -> Num)2003 ```2005 Computes the Bessel function of the first kind of order 0.2007 Argument | Type | Description | Default2008 ---------|------|-------------|---------2014 **Example:**2016 assert (0.0).j0() == 12018 ```2019 ## Num.j12022 Num.j1 : func(x: Num -> Num)2023 ```2025 Computes the Bessel function of the first kind of order 1.2027 Argument | Type | Description | Default2028 ---------|------|-------------|---------2034 **Example:**2036 assert (0.0).j1() == 02038 ```2039 ## Num.log2042 Num.log : func(x: Num -> Num)2043 ```2045 Computes the natural logarithm (base $e$) of a number.2047 Argument | Type | Description | Default2048 ---------|------|-------------|---------2054 **Example:**2056 assert Num.E.log() == 12058 ```2059 ## Num.log102062 Num.log10 : func(x: Num -> Num)2063 ```2065 Computes the base-10 logarithm of a number.2067 Argument | Type | Description | Default2068 ---------|------|-------------|---------2074 **Example:**2076 assert (100.0).log10() == 22078 ```2079 ## Num.log1p2082 Num.log1p : func(x: Num -> Num)2083 ```2085 Computes $\log(1 + x)$ for a number.2087 Argument | Type | Description | Default2088 ---------|------|-------------|---------2094 **Example:**2096 assert (1.0).log1p().near(0.6931471805599453)2098 ```2099 ## Num.log22102 Num.log2 : func(x: Num -> Num)2103 ```2105 Computes the base-2 logarithm of a number.2107 Argument | Type | Description | Default2108 ---------|------|-------------|---------2114 **Example:**2116 assert (8.0).log2() == 32118 ```2119 ## Num.logb2122 Num.logb : func(x: Num -> Num)2123 ```2125 Computes the binary exponent (base-2 logarithm) of a number.2127 Argument | Type | Description | Default2128 ---------|------|-------------|---------2134 **Example:**2136 assert (8.0).logb() == 32138 ```2139 ## Num.mix2142 Num.mix : func(amount: Num, x: Num, y: Num -> Num)2143 ```2145 Interpolates between two numbers based on a given amount.2147 Argument | Type | Description | Default2148 ---------|------|-------------|---------2156 **Example:**2158 assert (0.5).mix(10, 20) == 152159 assert (0.25).mix(10, 20) == 12.52161 ```2162 ## Num.near2165 Num.near : func(x: Num, y: Num, ratio: Num = 1e-9, min_epsilon: Num = 1e-9 -> Bool)2166 ```2168 Checks if two numbers are approximately equal within specified tolerances. If two numbers are within an absolute difference or the ratio between the two is small enough, they are considered near each other.2170 Argument | Type | Description | Default2171 ---------|------|-------------|---------2177 **Return:** `yes` if `x` and `y` are approximately equal within the specified tolerances, `no` otherwise.2180 **Example:**2182 assert (1.0).near(1.000000001) == yes2183 assert (100.0).near(110, ratio=0.1) == yes2184 assert (5.0).near(5.1, min_epsilon=0.1) == yes2186 ```2187 ## Num.nextafter2190 Num.nextafter : func(x: Num, y: Num -> Num)2191 ```2193 Computes the next representable value after a given number towards a specified direction.2195 Argument | Type | Description | Default2196 ---------|------|-------------|---------2203 **Example:**2205 assert (1.0).nextafter(1.1) == 1.00000000000000022207 ```2208 ## Num.parse2211 Num.parse : func(text: Text, remainder: &Text? = none -> Num?)2212 ```2214 Converts a text representation of a number into a floating-point number.2216 Argument | Type | Description | Default2217 ---------|------|-------------|---------2219 remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none`2221 **Return:** The number represented by the text or `none` if the entire text can't be parsed as a number.2224 **Example:**2226 assert Num.parse("3.14") == 3.142227 assert Num.parse("1e3") == 10002228 assert Num.parse("1.5junk") == none2229 remainder : Text2230 assert Num.parse("1.5junk", &remainder) == 1.52231 assert remainder == "junk"2233 ```2234 ## Num.percent2237 Num.percent : func(n: Num, precision: Num = 0.01 -> Text)2238 ```2240 Convert a number into a percentage text with a percent sign.2242 Argument | Type | Description | Default2243 ---------|------|-------------|---------2250 **Example:**2252 assert (0.5).percent() == "50%"2253 assert (1./3.).percent(2) == "34%"2254 assert (1./3.).percent(precision=0.0001) == "33.3333%"2255 assert (1./3.).percent(precision=10.) == "30%"2257 ```2258 ## Num.rint2261 Num.rint : func(x: Num -> Num)2262 ```2264 Rounds a number to the nearest integer, with ties rounded to the nearest even integer.2266 Argument | Type | Description | Default2267 ---------|------|-------------|---------2273 **Example:**2275 assert (3.5).rint() == 42276 assert (2.5).rint() == 22278 ```2279 ## Num.round2282 Num.round : func(x: Num -> Num)2283 ```2285 Rounds a number to the nearest whole number integer.2287 Argument | Type | Description | Default2288 ---------|------|-------------|---------2294 **Example:**2296 assert (2.3).round() == 22297 assert (2.7).round() == 32299 ```2300 ## Num.significand2303 Num.significand : func(x: Num -> Num)2304 ```2306 Extracts the significand (or mantissa) of a number.2308 Argument | Type | Description | Default2309 ---------|------|-------------|---------2315 **Example:**2317 assert (1234.567).significand() == 1.20563183593752319 ```2320 ## Num.sin2323 Num.sin : func(x: Num -> Num)2324 ```2326 Computes the sine of a number (angle in radians).2328 Argument | Type | Description | Default2329 ---------|------|-------------|---------2335 **Example:**2337 assert (0.0).sin() == 02339 ```2340 ## Num.sinh2343 Num.sinh : func(x: Num -> Num)2344 ```2346 Computes the hyperbolic sine of a number.2348 Argument | Type | Description | Default2349 ---------|------|-------------|---------2355 **Example:**2357 assert (0.0).sinh() == 02359 ```2360 ## Num.sqrt2363 Num.sqrt : func(x: Num -> Num)2364 ```2366 Computes the square root of a number.2368 Argument | Type | Description | Default2369 ---------|------|-------------|---------2375 **Example:**2377 assert (16.0).sqrt() == 42379 ```2380 ## Num.tan2383 Num.tan : func(x: Num -> Num)2384 ```2386 Computes the tangent of a number (angle in radians).2388 Argument | Type | Description | Default2389 ---------|------|-------------|---------2395 **Example:**2397 assert (0.0).tan() == 02399 ```2400 ## Num.tanh2403 Num.tanh : func(x: Num -> Num)2404 ```2406 Computes the hyperbolic tangent of a number.2408 Argument | Type | Description | Default2409 ---------|------|-------------|---------2415 **Example:**2417 assert (0.0).tanh() == 02419 ```2420 ## Num.tgamma2423 Num.tgamma : func(x: Num -> Num)2424 ```2426 Computes the gamma function of a number.2428 Argument | Type | Description | Default2429 ---------|------|-------------|---------2435 **Example:**2437 assert (1.0).tgamma() == 12439 ```2440 ## Num.trunc2443 Num.trunc : func(x: Num -> Num)2444 ```2446 Truncates a number to the nearest integer towards zero.2448 Argument | Type | Description | Default2449 ---------|------|-------------|---------2455 **Example:**2457 assert (3.7).trunc() == 32458 assert (-3.7).trunc() == -32460 ```2461 ## Num.with_precision2464 Num.with_precision : func(n: Num, precision: Num -> Num)2465 ```2469 Argument | Type | Description | Default2470 ---------|------|-------------|---------2477 **Example:**2479 assert (0.1234567).with_precision(0.01) == 0.122480 assert (123456.).with_precision(100) == 1235002481 assert (1234567.).with_precision(5) == 12345652483 ```2484 ## Num.y02487 Num.y0 : func(x: Num -> Num)2488 ```2490 Computes the Bessel function of the second kind of order 0.2492 Argument | Type | Description | Default2493 ---------|------|-------------|---------2499 **Example:**2501 assert (1.0).y0().near(0.08825696421567698)2503 ```2504 ## Num.y12507 Num.y1 : func(x: Num -> Num)2508 ```2510 Computes the Bessel function of the second kind of order 1.2512 Argument | Type | Description | Default2513 ---------|------|-------------|---------2519 **Example:**2521 assert (1.0).y1().near(-0.7812128213002887)2523 ```2525 # Path2526 ## Path.accessed2529 Path.accessed : func(path: Path, follow_symlinks: Bool = yes -> Int64?)2530 ```2532 Gets the file access time of a file.2534 Argument | Type | Description | Default2535 ---------|------|-------------|---------2539 **Return:** A 64-bit unix epoch timestamp representing when the file or directory was last accessed, or `none` if no such file or directory exists.2542 **Example:**2544 assert (./file.txt).accessed() == Int64(1704221100)2545 assert (./not-a-file).accessed() == none2547 ```2548 ## Path.append2551 Path.append : func(path: Path, text: Text, permissions: Int32 = Int32(0o644) -> Result)2552 ```2554 Appends the given text to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error.2556 Argument | Type | Description | Default2557 ---------|------|-------------|---------2560 permissions | `Int32` | The permissions to set on the file if it is being created. | `Int32(0o644)`2565 **Example:**2567 (./log.txt).append("extra line\n")!2569 ```2570 ## Path.append_bytes2573 Path.append_bytes : func(path: Path, bytes: [Byte], permissions: Int32 = Int32(0o644) -> Result)2574 ```2576 Appends the given bytes to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error.2578 Argument | Type | Description | Default2579 ---------|------|-------------|---------2582 permissions | `Int32` | The permissions to set on the file if it is being created. | `Int32(0o644)`2587 **Example:**2589 (./log.txt).append_bytes([104, 105])!2591 ```2592 ## Path.base_name2595 Path.base_name : func(path: Path -> Text)2596 ```2598 Returns the base name of the file or directory at the specified path.2600 Argument | Type | Description | Default2601 ---------|------|-------------|---------2607 **Example:**2609 assert (./path/to/file.txt).base_name() == "file.txt"2611 ```2612 ## Path.by_line2615 Path.by_line : func(path: Path -> func(->Text?)?)2616 ```2618 Returns an iterator that can be used to iterate over a file one line at a time, or returns none if the file could not be opened.2620 Argument | Type | Description | Default2621 ---------|------|-------------|---------2624 **Return:** An iterator that can be used to get lines from a file one at a time or none if the file couldn't be read.2627 **Example:**2629 # Safely handle file not being readable:2630 if lines := (./file.txt).by_line()2631 for line in lines2632 say(line.upper())2633 else2634 say("Couldn't read file!")2636 # Assume the file is readable and error if that's not the case:2637 for line in (/dev/stdin).by_line()!2638 say(line.upper())2640 ```2641 ## Path.byte_writer2644 Path.byte_writer : func(path: Path, append: Bool = no, permissions: Int32 = Int32(0o644) -> func(bytes:[Byte], close:Bool=no -> Result))2645 ```2647 Returns a function that can be used to repeatedly write bytes to the same file.2649 The file writer will keep its file descriptor open after each write (unless the `close` argument is set to `yes`). If the file writer is never closed, it will be automatically closed when the file writer is garbage collected.2651 Argument | Type | Description | Default2652 ---------|------|-------------|---------2654 append | `Bool` | If set to `yes`, writes to the file will append. If set to `no`, then the first write to the file will overwrite its contents and subsequent calls will append. | `no`2657 **Return:** Returns a function that can repeatedly write bytes to the same file. If `close` is set to `yes`, then the file will be closed after writing. If this function is called again after closing, the file will be reopened for appending.2660 **Example:**2662 write := (./file.txt).byte_writer()2663 write("Hello\n".utf8())!2664 write("world\n".utf8(), close=yes)!2666 ```2667 ## Path.can_execute2670 Path.can_execute : func(path: Path -> Bool)2671 ```2673 Returns whether or not a file can be executed by the current user/group.2675 Argument | Type | Description | Default2676 ---------|------|-------------|---------2679 **Return:** `yes` if the file or directory exists and the current user has execute permissions, otherwise `no`.2682 **Example:**2684 assert (/bin/sh).can_execute() == yes2685 assert (/usr/include/stdlib.h).can_execute() == no2686 assert (/non/existant/file).can_execute() == no2688 ```2689 ## Path.can_read2692 Path.can_read : func(path: Path -> Bool)2693 ```2695 Returns whether or not a file can be read by the current user/group.2697 Argument | Type | Description | Default2698 ---------|------|-------------|---------2701 **Return:** `yes` if the file or directory exists and the current user has read permissions, otherwise `no`.2704 **Example:**2706 assert (/usr/include/stdlib.h).can_read() == yes2707 assert (/etc/shadow).can_read() == no2708 assert (/non/existant/file).can_read() == no2710 ```2711 ## Path.can_write2714 Path.can_write : func(path: Path -> Bool)2715 ```2717 Returns whether or not a file can be written by the current user/group.2719 Argument | Type | Description | Default2720 ---------|------|-------------|---------2723 **Return:** `yes` if the file or directory exists and the current user has write permissions, otherwise `no`.2726 **Example:**2728 assert (/tmp).can_write() == yes2729 assert (/etc/passwd).can_write() == no2730 assert (/non/existant/file).can_write() == no2732 ```2733 ## Path.changed2736 Path.changed : func(path: Path, follow_symlinks: Bool = yes -> Int64?)2737 ```2739 Gets the file change time of a file.2741 This is the ["ctime"](https://en.wikipedia.org/wiki/Stat_(system_call)#ctime) of a file, which is _not_ the file creation time.2743 Argument | Type | Description | Default2744 ---------|------|-------------|---------2748 **Return:** A 64-bit unix epoch timestamp representing when the file or directory was last changed, or `none` if no such file or directory exists.2751 **Example:**2753 assert (./file.txt).changed() == Int64(1704221100)2754 assert (./not-a-file).changed() == none2756 ```2757 ## Path.child2760 Path.child : func(path: Path, child: Text -> Path)2761 ```2763 Return a path that is a child of another path.2765 Argument | Type | Description | Default2766 ---------|------|-------------|---------2773 **Example:**2775 assert (./directory).child("file.txt") == (./directory/file.txt)2777 ```2778 ## Path.children2781 Path.children : func(path: Path, include_hidden = no -> [Path])2782 ```2784 Returns a list of children (files and directories) within the directory at the specified path. Optionally includes hidden files. Child ordering is not specified.2786 Argument | Type | Description | Default2787 ---------|------|-------------|---------2794 **Example:**2796 assert (./directory).children(include_hidden=yes) == [(./directory/.git), (./directory/foo.txt)]2798 ```2799 ## Path.create_directory2802 Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Result)2803 ```2805 Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed.2808 Argument | Type | Description | Default2809 ---------|------|-------------|---------2812 recursive | `` | If set to `yes`, then recursively create any parent directories if they don't exist, otherwise fail if the parent directory does not exist. When set to `yes`, this function behaves like `mkdir -p`. | `yes`2817 **Example:**2819 (./new_directory).create_directory()!2821 ```2822 ## Path.current_dir2825 Path.current_dir : func(-> Path)2826 ```2828 Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed.2834 **Example:**2836 assert Path.current_dir() == (/home/user/tomo)2838 ```2839 ## Path.each_child2842 Path.each_child : func(path: Path, include_hidden = no -> func(->Path?)?)2843 ```2845 Returns an iterator over the children (files and directories) within the directory at the specified path. Optionally includes hidden files. Iteration order is not specified.2847 Argument | Type | Description | Default2848 ---------|------|-------------|---------2852 **Return:** An iterator over the children in a directory or `none` if the path is not a directory or a symlink to a directory.2855 **Example:**2857 for child in (/dir).each_child()2858 say("Child: $child")2860 ```2861 ## Path.exists2864 Path.exists : func(path: Path -> Bool)2865 ```2867 Checks if a file or directory exists at the specified path.2869 Argument | Type | Description | Default2870 ---------|------|-------------|---------2876 **Example:**2878 assert (/).exists() == yes2880 ```2881 ## Path.expand_home2884 Path.expand_home : func(path: Path -> Path)2885 ```2887 For home-based paths (those starting with `~`), expand the path to replace the tilde with and absolute path to the user's `$HOME` directory.2889 Argument | Type | Description | Default2890 ---------|------|-------------|---------2893 **Return:** If the path does not start with a `~`, then return it unmodified. Otherwise, replace the `~` with an absolute path to the user's home directory.2896 **Example:**2898 # Assume current user is 'user'2899 assert (~/foo).expand_home() == (/home/user/foo)2900 # No change2901 assert (/foo).expand_home() == (/foo)2903 ```2904 ## Path.extension2907 Path.extension : func(path: Path, full: Bool = yes -> Text)2908 ```2910 Returns the file extension of the file at the specified path. Optionally returns the full extension.2912 Argument | Type | Description | Default2913 ---------|------|-------------|---------2915 full | `Bool` | Whether to return everything after the first `.` in the base name, or only the last part of the extension. | `yes`2917 **Return:** The file extension (not including the leading `.`) or an empty text if there is no file extension.2920 **Example:**2922 assert (./file.tar.gz).extension() == "tar.gz"2923 assert (./file.tar.gz).extension(full=no) == "gz"2924 assert (/foo).extension() == ""2925 assert (./.git).extension() == ""2927 ```2928 ## Path.files2931 Path.files : func(path: Path, include_hidden: Bool = no -> [Path])2932 ```2934 Returns a list of files within the directory at the specified path. Optionally includes hidden files.2936 Argument | Type | Description | Default2937 ---------|------|-------------|---------2944 **Example:**2946 assert (./directory).files(include_hidden=yes) == [(./directory/file1.txt), (./directory/file2.txt)]2948 ```2949 ## Path.glob2952 Path.glob : func(path: Path -> [Path])2953 ```2955 Perform a globbing operation and return a list of matching paths. Some glob specific details:2959 choices of patterns.2963 Argument | Type | Description | Default2964 ---------|------|-------------|---------2965 path | `Path` | The path of the directory which may contain special globbing characters like `*`, `?`, or `{...}` | -2970 **Example:**2972 # Current directory includes: foo.txt, baz.txt, qux.jpg, .hidden2973 assert (./*).glob() == [(./foo.txt), (./baz.txt), (./qux.jpg)]2974 assert (./*.txt).glob() == [(./foo.txt), (./baz.txt)]2975 assert (./*.{txt,jpg}).glob() == [(./foo.txt), (./baz.txt), (./qux.jpg)]2976 assert (./.*).glob() == [(./.hidden)]2978 # Globs with no matches return an empty list:2979 assert (./*.xxx).glob() == []2981 ```2982 ## Path.group2985 Path.group : func(path: Path, follow_symlinks: Bool = yes -> Text?)2986 ```2988 Get the owning group of a file or directory.2990 Argument | Type | Description | Default2991 ---------|------|-------------|---------2995 **Return:** The name of the group which owns the file or directory, or `none` if the path does not exist.2998 **Example:**3000 assert (/bin).group() == "root"3001 assert (/non/existent/file).group() == none3003 ```3004 ## Path.has_extension3007 Path.has_extension : func(path: Path, extension: Text -> Bool)3008 ```3010 Return whether or not a path has a given file extension.3012 Argument | Type | Description | Default3013 ---------|------|-------------|---------3015 extension | `Text` | A file extension (leading `.` is optional). If empty, the check will test if the file does not have any file extension. | -3020 **Example:**3022 assert (/foo.txt).has_extension("txt") == yes3023 assert (/foo.txt).has_extension(".txt") == yes3024 assert (/foo.tar.gz).has_extension("gz") == yes3025 assert (/foo.tar.gz).has_extension("zip") == no3027 ```3028 ## Path.is_directory3031 Path.is_directory : func(path: Path, follow_symlinks = yes -> Bool)3032 ```3034 Checks if the path represents a directory. Optionally follows symbolic links.3036 Argument | Type | Description | Default3037 ---------|------|-------------|---------3044 **Example:**3046 assert (./directory/).is_directory() == yes3047 assert (./file.txt).is_directory() == no3049 ```3050 ## Path.is_file3053 Path.is_file : func(path: Path, follow_symlinks = yes -> Bool)3054 ```3056 Checks if the path represents a file. Optionally follows symbolic links.3058 Argument | Type | Description | Default3059 ---------|------|-------------|---------3066 **Example:**3068 assert (./file.txt).is_file() == yes3069 assert (./directory/).is_file() == no3071 ```3072 ## Path.is_socket3075 Path.is_socket : func(path: Path, follow_symlinks = yes -> Bool)3076 ```3078 Checks if the path represents a socket. Optionally follows symbolic links.3080 Argument | Type | Description | Default3081 ---------|------|-------------|---------3088 **Example:**3090 assert (./socket).is_socket() == yes3092 ```3093 ## Path.is_symlink3096 Path.is_symlink : func(path: Path -> Bool)3097 ```3099 Checks if the path represents a symbolic link.3101 Argument | Type | Description | Default3102 ---------|------|-------------|---------3108 **Example:**3110 assert (./link).is_symlink() == yes3112 ```3113 ## Path.lines3116 Path.lines : func(path: Path -> [Text]?)3117 ```3119 Returns a list with the lines of text in a file or returns none if the file could not be opened.3121 Argument | Type | Description | Default3122 ---------|------|-------------|---------3128 **Example:**3130 lines := (./file.txt).lines()!3132 ```3133 ## Path.matches_glob3136 Path.matches_glob : func(path: Path, glob: Text -> Bool)3137 ```3139 Return whether or not a path matches a given glob.3141 Argument | Type | Description | Default3142 ---------|------|-------------|---------3149 **Example:**3151 assert (./file.txt).matches_glob("*.txt")3152 assert (./file.c).matches_glob("*.{c,h}")3154 ```3155 ## Path.modified3158 Path.modified : func(path: Path, follow_symlinks: Bool = yes -> Int64?)3159 ```3161 Gets the file modification time of a file.3163 Argument | Type | Description | Default3164 ---------|------|-------------|---------3168 **Return:** A 64-bit unix epoch timestamp representing when the file or directory was last modified, or `none` if no such file or directory exists.3171 **Example:**3173 assert (./file.txt).modified() == Int64(1704221100)3174 assert (./not-a-file).modified() == none3176 ```3177 ## Path.move3180 Path.move : func(path: Path, dest: Path, allow_overwriting = no -> Result)3181 ```3183 Moves the file or directory from one location to another.3185 Argument | Type | Description | Default3186 ---------|------|-------------|---------3189 allow_overwriting | `` | Whether to permit overwriting the destination if it is an existing file or directory. | `no`3194 **Example:**3196 (./file.txt).move(/tmp/renamed.txt)!3198 ```3199 ## Path.owner3202 Path.owner : func(path: Path, follow_symlinks: Bool = yes -> Text?)3203 ```3205 Get the owning user of a file or directory.3207 Argument | Type | Description | Default3208 ---------|------|-------------|---------3212 **Return:** The name of the user who owns the file or directory, or `none` if the path does not exist.3215 **Example:**3217 assert (/bin).owner() == "root"3218 assert (/non/existent/file).owner() == none3220 ```3221 ## Path.parent3224 Path.parent : func(path: Path -> Path?)3225 ```3227 Returns the parent directory of the file or directory at the specified path.3229 Argument | Type | Description | Default3230 ---------|------|-------------|---------3236 **Example:**3238 assert (./path/to/file.txt).parent() == (./path/to/)3240 ```3241 ## Path.read3244 Path.read : func(path: Path -> Text?)3245 ```3247 Reads the contents of the file at the specified path or none if the file could not be read.3249 Argument | Type | Description | Default3250 ---------|------|-------------|---------3253 **Return:** The contents of the file. If the file could not be read, none will be returned. If the file can be read, but is not valid UTF8 data, an error will be raised.3256 **Example:**3258 assert (./hello.txt).read() == "Hello"3259 assert (./nosuchfile.xxx).read() == none3261 ```3262 ## Path.read_bytes3265 Path.read_bytes : func(path: Path, limit: Int? = none -> [Byte]?)3266 ```3268 Reads the contents of the file at the specified path or none if the file could not be read.3270 Argument | Type | Description | Default3271 ---------|------|-------------|---------3278 **Example:**3280 assert (./hello.txt).read_bytes()! == [72, 101, 108, 108, 111]3281 assert (./nosuchfile.xxx).read_bytes() == none3283 ```3284 ## Path.relative_to3287 Path.relative_to : func(path: Path, relative_to = (./) -> Path)3288 ```3290 Returns the path relative to a given base path. By default, the base path is the current directory.3292 Argument | Type | Description | Default3293 ---------|------|-------------|---------3300 **Example:**3302 assert (./path/to/file.txt).relative_to((./path)) == (./to/file.txt)3303 assert (/tmp/foo).relative_to((/tmp)) == (./foo)3305 ```3306 ## Path.remove3309 Path.remove : func(path: Path, ignore_missing = no -> Result)3310 ```3312 Removes the file or directory at the specified path. A runtime error is raised if something goes wrong.3314 Argument | Type | Description | Default3315 ---------|------|-------------|---------3322 **Example:**3324 (./file.txt).remove()!3326 ```3327 ## Path.resolved3330 Path.resolved : func(path: Path, relative_to = (./) -> Path)3331 ```3333 Resolves the absolute path of the given path relative to a base path. By default, the base path is the current directory.3335 Argument | Type | Description | Default3336 ---------|------|-------------|---------3343 **Example:**3345 assert (~/foo).resolved() == (/home/user/foo)3346 assert (./path/to/file.txt).resolved(relative_to=(/foo)) == (/foo/path/to/file.txt)3348 ```3349 ## Path.set_owner3352 Path.set_owner : func(path: Path, owner: Text? = none, group: Text? = none, follow_symlinks: Bool = yes -> Result)3353 ```3355 Set the owning user and/or group for a path.3357 Argument | Type | Description | Default3358 ---------|------|-------------|---------3367 **Example:**3369 (./file.txt).set_owner(owner="root", group="wheel")!3371 ```3372 ## Path.sibling3375 Path.sibling : func(path: Path, name: Text -> Path)3376 ```3378 Return a path that is a sibling of another path (i.e. has the same parent, but a different name). This is equivalent to `.parent().child(name)`3380 Argument | Type | Description | Default3381 ---------|------|-------------|---------3388 **Example:**3390 assert (/foo/baz).sibling("doop") == (/foo/doop)3392 ```3393 ## Path.subdirectories3396 Path.subdirectories : func(path: Path, include_hidden = no -> [Path])3397 ```3399 Returns a list of subdirectories within the directory at the specified path. Optionally includes hidden subdirectories.3401 Argument | Type | Description | Default3402 ---------|------|-------------|---------3404 include_hidden | `` | Whether to include hidden subdirectories (those starting with a `.`) | `no`3409 **Example:**3411 assert (./directory).subdirectories() == [(./directory/subdir1), (./directory/subdir2)]3412 assert (./directory).subdirectories(include_hidden=yes) == [(./directory/.git), (./directory/subdir1), (./directory/subdir2)]3414 ```3415 ## Path.unique_directory3418 Path.unique_directory : func(path: Path -> Path)3419 ```3421 Generates a unique directory path based on the given path. Useful for creating temporary directories.3423 Argument | Type | Description | Default3424 ---------|------|-------------|---------3425 path | `Path` | The base path for generating the unique directory. The last six letters of this path must be `XXXXXX`. | -3430 **Example:**3432 created := (/tmp/my-dir.XXXXXX).unique_directory()3433 assert created.is_directory() == yes3434 created.remove()!3436 ```3437 ## Path.walk3440 Path.walk : func(path: Path, include_hidden = no, follow_symlinks: Bool = no -> func(->Path?))3441 ```3443 Returns an iterator that efficiently recursively walks over every file and subdirectory in a given directory. The iteration order is not defined, but in practice it may look a lot like a breadth-first traversal.3445 The path itself is always included in the iteration.3447 Argument | Type | Description | Default3448 ---------|------|-------------|---------3451 follow_symlinks | `Bool` | Whether to follow symbolic links. Caution: if set to 'yes', it is possible for this iterator to get stuck in a loop, using increasingly large amounts of memory. | `no`3456 **Example:**3458 for p in (/tmp).walk()3459 say("File or dir: $p")3461 # The path itself is always included:3462 assert [p for p in (./file.txt).walk()] == [(./file.txt)]3464 ```3465 ## Path.write3468 Path.write : func(path: Path, text: Text, permissions = Int32(0o644) -> Result)3469 ```3471 Writes the given text to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised.3473 Argument | Type | Description | Default3474 ---------|------|-------------|---------3482 **Example:**3484 (./file.txt).write("Hello, world!")!3486 ```3487 ## Path.write_bytes3490 Path.write_bytes : func(path: Path, bytes: [Byte], permissions = Int32(0o644) -> Result)3491 ```3493 Writes the given bytes to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised.3495 Argument | Type | Description | Default3496 ---------|------|-------------|---------3504 **Example:**3506 (./file.txt).write_bytes([104, 105])!3508 ```3509 ## Path.write_unique3512 Path.write_unique : func(path: Path, text: Text -> Path)3513 ```3515 Writes the given text to a unique file path based on the specified path. The file is created if it doesn't exist. This is useful for creating temporary files.3517 Argument | Type | Description | Default3518 ---------|------|-------------|---------3519 path | `Path` | The base path for generating the unique file. This path must include the string `XXXXXX` in the file base name. | -3525 **Example:**3527 created := (./file-XXXXXX.txt).write_unique("Hello, world!")!3528 assert created == (./file-27QHtq.txt)3529 assert created.read()! == "Hello, world!"3530 created.remove()!3532 ```3533 ## Path.write_unique_bytes3536 Path.write_unique_bytes : func(path: Path, bytes: [Byte] -> Path)3537 ```3539 Writes the given bytes to a unique file path based on the specified path. The file is created if it doesn't exist. This is useful for creating temporary files.3541 Argument | Type | Description | Default3542 ---------|------|-------------|---------3543 path | `Path` | The base path for generating the unique file. This path must include the string `XXXXXX` in the file base name. | -3549 **Example:**3551 created := (./file-XXXXXX.txt).write_unique_bytes([1, 2, 3])!3552 assert created == (./file-27QHtq.txt)3553 assert created.read_bytes()! == [1, 2, 3]3554 created.remove()!3556 ```3557 ## Path.writer3560 Path.writer : func(path: Path, append: Bool = no, permissions: Int32 = Int32(0o644) -> func(text:Text, close:Bool=no -> Result))3561 ```3563 Returns a function that can be used to repeatedly write to the same file.3565 The file writer will keep its file descriptor open after each write (unless the `close` argument is set to `yes`). If the file writer is never closed, it will be automatically closed when the file writer is garbage collected.3567 Argument | Type | Description | Default3568 ---------|------|-------------|---------3570 append | `Bool` | If set to `yes`, writes to the file will append. If set to `no`, then the first write to the file will overwrite its contents and subsequent calls will append. | `no`3573 **Return:** Returns a function that can repeatedly write to the same file. If `close` is set to `yes`, then the file will be closed after writing. If this function is called again after closing, the file will be reopened for appending.3576 **Example:**3578 write := (./file.txt).writer()3579 write("Hello\n")!3580 write("world\n", close=yes)!3582 ```3584 # Table3585 ## Table.clear3588 Table.clear : func(t: &{K:V} -> Void)3589 ```3591 Removes all key-value pairs from the table.3593 Argument | Type | Description | Default3594 ---------|------|-------------|---------3600 **Example:**3602 t := &{"A":1}3603 t.clear()3604 assert t[] == {}3606 ```3607 ## Table.difference3610 Table.difference : func(t: {K:V}, other: {K:V} -> {K:V})3611 ```3613 Return a table whose key/value pairs correspond to keys only present in one table, but not the other.3615 Argument | Type | Description | Default3616 ---------|------|-------------|---------3623 **Example:**3625 t1 := {"A": 1, "B": 2, "C": 3}3626 t2 := {"B": 2, "C":30, "D": 40}3627 assert t1.difference(t2) == {"A": 1, "D": 40}3629 ```3630 ## Table.get3633 Table.get : func(t: {K:V}, key: K -> V?)3634 ```3638 Default values for the table are ignored.3640 Argument | Type | Description | Default3641 ---------|------|-------------|---------3648 **Example:**3650 t := {"A": 1, "B": 2}3651 assert t.get("A") == 13652 assert t.get("????") == none3653 assert t.get("A")! == 13654 assert t.get("????") or 0 == 03656 ```3657 ## Table.get_or_set3660 Table.get_or_set : func(t: &{K:V}, key: K, default: V -> V?)3661 ```3663 If the given key is in the table, return the associated value. Otherwise, insert the given default value into the table and return it.3665 If no default value is provided explicitly, but the table has a default value associated with it, the table's default value will be used.3666 The default value is only evaluated if the key is missing.3668 Argument | Type | Description | Default3669 ---------|------|-------------|---------3672 default | `V` | The default value to insert and return if the key is not present in the table. | -3674 **Return:** Either the value associated with the key (if present) or the default value. The table will be mutated if the key is not already present.3677 **Example:**3679 t := &{"A": @[1, 2, 3]; default=@[]}3680 t.get_or_set("A").insert(4)3681 t.get_or_set("B").insert(99)3682 assert t["A"][] == [1, 2, 3, 4]3683 assert t["B"][] == [99]3684 assert t.get_or_set("C", @[0, 0, 0])[] == [0, 0, 0]3686 ```3687 ## Table.has3690 Table.has : func(t: {K:V}, key: K -> Bool)3691 ```3693 Checks if the table contains a specified key.3695 Argument | Type | Description | Default3696 ---------|------|-------------|---------3703 **Example:**3705 assert {"A": 1, "B": 2}.has("A") == yes3706 assert {"A": 1, "B": 2}.has("xxx") == no3708 ```3709 ## Table.intersection3712 Table.intersection : func(t: {K:V}, other: {K:V} -> {K:V})3713 ```3715 Return a table with only the matching key/value pairs that are common to both tables.3717 Argument | Type | Description | Default3718 ---------|------|-------------|---------3725 **Example:**3727 t1 := {"A": 1, "B": 2, "C": 3}3728 t2 := {"B": 2, "C":30, "D": 40}3729 assert t1.intersection(t2) == {"B": 2}3731 ```3732 ## Table.remove3735 Table.remove : func(t: {K:V}, key: K -> Void)3736 ```3738 Removes the key-value pair associated with a specified key.3740 Argument | Type | Description | Default3741 ---------|------|-------------|---------3748 **Example:**3750 t := &{"A": 1, "B": 2}3751 t.remove("A")3752 assert t == {"B": 2}3754 ```3755 ## Table.set3758 Table.set : func(t: {K:V}, key: K, value: V -> Void)3759 ```3761 Sets or updates the value associated with a specified key.3763 Argument | Type | Description | Default3764 ---------|------|-------------|---------3772 **Example:**3774 t := &{"A": 1, "B": 2}3775 t.set("C", 3)3776 assert t == {"A": 1, "B": 2, "C": 3}3778 ```3779 ## Table.with3782 Table.with : func(t: {K:V}, other: {K:V} -> {K:V})3783 ```3785 Return a copy of a table with values added from another table3787 Argument | Type | Description | Default3788 ---------|------|-------------|---------3795 **Example:**3797 t := {"A": 1, "B": 2}3798 assert t.with({"B": 20, "C": 30}) == {"A": 1, "B": 20, "C": 30}3800 ```3801 ## Table.with_fallback3804 Table.with_fallback : func(t: {K:V}, fallback: {K:V}? -> {K:V})3805 ```3807 Return a copy of a table with a different fallback table.3809 Argument | Type | Description | Default3810 ---------|------|-------------|---------3817 **Example:**3819 t := {"A": 1; fallback={"B": 2}}3820 t2 := t.with_fallback({"B": 3})3821 assert t2["B"] == 33822 t3 := t.with_fallback(none)3823 assert t3["B"] == none3825 ```3826 ## Table.without3829 Table.without : func(t: {K:V}, other: {K:V} -> {K:V})3830 ```3832 Return a copy of a table, but without any of the exact key/value pairs found in the other table.3834 Only exact key/value pairs will be discarded. Keys with a non-matching value will be kept.3836 Argument | Type | Description | Default3837 ---------|------|-------------|---------3844 **Example:**3846 t := {"A": 1, "B": 2, "C": 3}3847 assert t.without({"B": 2, "C": 30, "D": 40}) == {"A": 1, "C": 3}3849 ```3851 # Text3852 ## Text.as_c_string3855 Text.as_c_string : func(text: Text -> CString)3856 ```3860 Argument | Type | Description | Default3861 ---------|------|-------------|---------3867 **Example:**3869 assert "Hello".as_c_string() == CString("Hello")3871 ```3872 ## Text.at3875 Text.at : func(text: Text, index: Int -> Text)3876 ```3878 Get the graphical cluster at a given index. This is similar to `str[i]` with ASCII text, but has more correct behavior for unicode text.3880 Negative indices are counted from the back of the text, so `-1` means the last cluster, `-2` means the second-to-last, and so on.3882 Argument | Type | Description | Default3883 ---------|------|-------------|---------3890 **Example:**3892 assert "Amélie".at(3) == "é"3894 ```3895 ## Text.by_line3898 Text.by_line : func(text: Text -> func(->Text?))3899 ```3901 Returns an iterator function that can be used to iterate over the lines in a text.3903 This function ignores a trailing newline if there is one. If you don't want this behavior, use `text.by_split($/{1 nl}/)` instead.3905 Argument | Type | Description | Default3906 ---------|------|-------------|---------3909 **Return:** An iterator function that returns one line at a time, until it runs out and returns `none`.3912 **Example:**3914 text := "3915 line one3916 line two3917 "3918 lines := [line for line in text.by_line()]3919 assert lines == ["line one", "line two"]3921 ```3922 ## Text.by_split3925 Text.by_split : func(text: Text, delimiter: Text = "" -> func(->Text?))3926 ```3928 Returns an iterator function that can be used to iterate over text separated by a delimiter.3930 To split based on a set of delimiters, use Text.by_split_any().3931 If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.3933 Argument | Type | Description | Default3934 ---------|------|-------------|---------3938 **Return:** An iterator function that returns one chunk of text at a time, separated by the given delimiter, until it runs out and returns `none`.3941 **Example:**3943 text := "one,two,three"3944 chunks := [chunk for chunk in text.by_split(",")]3945 assert chunks == ["one", "two", "three"]3947 ```3948 ## Text.by_split_any3951 Text.by_split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> func(->Text?))3952 ```3954 Returns an iterator function that can be used to iterate over text separated by one or more characters (grapheme clusters) from a given text of delimiters.3956 Splitting will occur on every place where one or more of the grapheme clusters in `delimiters` occurs.3957 To split based on an exact delimiter, use Text.by_split().3959 Argument | Type | Description | Default3960 ---------|------|-------------|---------3964 **Return:** An iterator function that returns one chunk of text at a time, separated by the given delimiter characters, until it runs out and returns `none`.3967 **Example:**3969 text := "one,two,;,three"3970 chunks := [chunk for chunk in text.by_split_any(",;")]3971 assert chunks == ["one", "two", "three"]3973 ```3974 ## Text.caseless_equals3977 Text.caseless_equals : func(a: Text, b: Text, language: Text = "C" -> Bool)3978 ```3980 Checks whether two texts are equal, ignoring the casing of the letters (i.e. case-insensitive comparison).3982 Argument | Type | Description | Default3983 ---------|------|-------------|---------3991 **Example:**3993 assert "A".caseless_equals("a") == yes3995 # Turkish lowercase "I" is "ı" (dotless I), not "i"3996 assert "I".caseless_equals("i", language="tr_TR") == no3998 ```3999 ## Text.codepoint_names4002 Text.codepoint_names : func(text: Text -> [Text])4003 ```4005 Returns a list of the names of each codepoint in the text.4007 Argument | Type | Description | Default4008 ---------|------|-------------|---------4014 **Example:**4016 assert "Amélie".codepoint_names() == [4017 "LATIN CAPITAL LETTER A",4018 "LATIN SMALL LETTER M",4019 "LATIN SMALL LETTER E WITH ACUTE",4020 "LATIN SMALL LETTER L",4021 "LATIN SMALL LETTER I",4022 "LATIN SMALL LETTER E",4023 ]4025 ```4026 ## Text.distance4029 Text.distance : func(a: Text, b: Text, language: Text = "C" -> Num)4030 ```4032 Get an approximate distance between two texts, such that when the distance is small, the texts are similar and when the distance is large, the texts are dissimilar.4034 The exact distance algorithm is not specified and may be subject to change over time.4036 Argument | Type | Description | Default4037 ---------|------|-------------|---------4045 **Example:**4047 assert "hello".distance("hello") == 04048 texts := &["goodbye", "hello", "hallo"]4049 texts.sort(func(a,b:&Text) a.distance("hello") <> b.distance("hello"))4050 assert texts == ["hello", "hallo", "goodbye"]4052 ```4053 ## Text.ends_with4056 Text.ends_with : func(text: Text, suffix: Text, remainder: &Text? = none -> Bool)4057 ```4061 Argument | Type | Description | Default4062 ---------|------|-------------|---------4065 remainder | `&Text?` | If non-none, this value will be set to the rest of the text up to the trailing suffix. If the suffix is not found, this value will be set to the original text. | `none`4070 **Example:**4072 assert "hello world".ends_with("world") == yes4073 remainder : Text4074 assert "hello world".ends_with("world", &remainder) == yes4075 assert remainder == "hello "4077 ```4078 ## Text.find4081 Text.find : func(text: Text, target: Text, start: Int = 1 -> Int)4082 ```4084 Find a substring within a text and return its index, if found.4086 Argument | Type | Description | Default4087 ---------|------|-------------|---------4092 **Return:** The index where the first occurrence of `target` appears, or `none` if it is not found.4095 **Example:**4097 assert "one two".find("one") == 14098 assert "one two".find("two") == 54099 assert "one two".find("three") == none4100 assert "one two".find("o", start=2) == 74102 ```4103 ## Text.from4106 Text.from : func(text: Text, first: Int -> Text)4107 ```4109 Get a slice of the text, starting at the given position.4111 A negative index counts backwards from the end of the text, so `-1` refers to the last cluster, `-2` the second-to-last, etc. Slice ranges will be truncated to the length of the text.4113 Argument | Type | Description | Default4114 ---------|------|-------------|---------4121 **Example:**4123 assert "hello".from(2) == "ello"4124 assert "hello".from(-2) == "lo"4126 ```4127 ## Text.from_c_string4130 Text.from_c_string : func(str: CString -> Text)4131 ```4135 Argument | Type | Description | Default4136 ---------|------|-------------|---------4142 **Example:**4144 assert Text.from_c_string(CString("Hello")) == "Hello"4146 ```4147 ## Text.from_codepoint_names4150 Text.from_codepoint_names : func(codepoint_names: [Text] -> [Text])4151 ```4153 Returns text that has the given codepoint names (according to the Unicode specification) as its codepoints.4155 The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.4157 Argument | Type | Description | Default4158 ---------|------|-------------|---------4159 codepoint_names | `[Text]` | The names of each codepoint in the desired text (case-insentive). | -4161 **Return:** A new text with the specified codepoints after normalization has been applied. Any invalid names are ignored.4164 **Example:**4166 text := Text.from_codepoint_names([4167 "LATIN CAPITAL LETTER A WITH RING ABOVE",4168 "LATIN SMALL LETTER K",4169 "LATIN SMALL LETTER E",4170 ])4171 assert text == "Åke"4173 ```4174 ## Text.from_utf164177 Text.from_utf16 : func(bytes: [Int16] -> [Text])4178 ```4180 Returns text that has been constructed from the given UTF16 sequence.4182 The text will be normalized, so the resulting text's UTF16 sequence may not exactly match the input.4184 Argument | Type | Description | Default4185 ---------|------|-------------|---------4191 **Example:**4193 assert Text.from_utf16([197, 107, 101]) == "Åke"4194 assert Text.from_utf16([12371, 12435, 12395, 12385, 12399, 19990, 30028]) == "こんにちは世界"4196 ```4197 ## Text.from_utf324200 Text.from_utf32 : func(codepoints: [Int32] -> [Text])4201 ```4203 Returns text that has been constructed from the given UTF32 codepoints.4205 The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.4207 Argument | Type | Description | Default4208 ---------|------|-------------|---------4214 **Example:**4216 assert Text.from_utf32([197, 107, 101]) == "Åke"4218 ```4219 ## Text.from_utf84222 Text.from_utf8 : func(bytes: [Byte] -> [Text])4223 ```4225 Returns text that has been constructed from the given UTF8 bytes.4227 The text will be normalized, so the resulting text's UTF8 bytes may not exactly match the input.4229 Argument | Type | Description | Default4230 ---------|------|-------------|---------4236 **Example:**4238 assert Text.from_utf8([195, 133, 107, 101]) == "Åke"4240 ```4241 ## Text.has4244 Text.has : func(text: Text, target: Text -> Bool)4245 ```4249 Argument | Type | Description | Default4250 ---------|------|-------------|---------4257 **Example:**4259 assert "hello world".has("wo") == yes4260 assert "hello world".has("xxx") == no4262 ```4263 ## Text.join4266 Text.join : func(glue: Text, pieces: [Text] -> Text)4267 ```4269 Joins a list of text pieces with a specified glue.4271 Argument | Type | Description | Default4272 ---------|------|-------------|---------4279 **Example:**4281 assert ", ".join(["one", "two", "three"]) == "one, two, three"4283 ```4284 ## Text.left_pad4287 Text.left_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)4288 ```4290 Pad some text on the left side so it reaches a target width.4292 Argument | Type | Description | Default4293 ---------|------|-------------|---------4299 **Return:** Text with length at least `width`, with extra padding on the left as needed. If `pad` has length greater than 1, it may be partially repeated to reach the exact desired length.4302 **Example:**4304 assert "x".left_pad(5) == " x"4305 assert "x".left_pad(5, "ABC") == "ABCAx"4307 ```4308 ## Text.lines4311 Text.lines : func(text: Text -> [Text])4312 ```4314 Splits the text into a list of lines of text, preserving blank lines, ignoring trailing newlines, and handling `\r\n` the same as `\n`.4316 Argument | Type | Description | Default4317 ---------|------|-------------|---------4323 **Example:**4325 assert "one\ntwo\nthree".lines() == ["one", "two", "three"]4326 assert "one\ntwo\nthree\n".lines() == ["one", "two", "three"]4327 assert "one\ntwo\nthree\n\n".lines() == ["one", "two", "three", ""]4328 assert "one\r\ntwo\r\nthree\r\n".lines() == ["one", "two", "three"]4329 assert "".lines() == []4331 ```4332 ## Text.lower4335 Text.lower : func(text: Text, language: Text = "C" -> Text)4336 ```4338 Converts all characters in the text to lowercase.4340 Argument | Type | Description | Default4341 ---------|------|-------------|---------4348 **Example:**4350 assert "AMÉLIE".lower() == "amélie"4351 assert "I".lower(language="tr_TR") == "ı"4353 ```4354 ## Text.matches_glob4357 Text.matches_glob : func(path: Text, glob: Text -> Bool)4358 ```4360 Return whether or not the text matches the given glob.4362 Argument | Type | Description | Default4363 ---------|------|-------------|---------4370 **Example:**4372 assert "hello world".matches_glob("h* *d")4374 ```4375 ## Text.middle_pad4378 Text.middle_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)4379 ```4381 Pad some text on the left and right side so it reaches a target width.4383 Argument | Type | Description | Default4384 ---------|------|-------------|---------4390 **Return:** Text with length at least `width`, with extra padding on the left and right as needed. If `pad` has length greater than 1, it may be partially repeated to reach the exact desired length.4393 **Example:**4395 assert "x".middle_pad(6) == " x "4396 assert "x".middle_pad(10, "ABC") == "ABCAxABCAB"4398 ```4399 ## Text.quoted4402 Text.quoted : func(text: Text, color: Bool = no, quotation_mark: Text = `"` -> Text)4403 ```4405 Formats the text with quotation marks and escapes.4407 Argument | Type | Description | Default4408 ---------|------|-------------|---------4416 **Example:**4418 assert "one\ntwo".quoted() == "\"one\\ntwo\""4420 ```4421 ## Text.repeat4424 Text.repeat : func(text: Text, count: Int -> Text)4425 ```4427 Repeat some text multiple times.4429 Argument | Type | Description | Default4430 ---------|------|-------------|---------4432 count | `Int` | The number of times to repeat it. (Negative numbers are equivalent to zero). | -4437 **Example:**4439 assert "Abc".repeat(3) == "AbcAbcAbc"4441 ```4442 ## Text.replace4445 Text.replace : func(text: Text, target: Text, replacement: Text -> Text)4446 ```4448 Replaces occurrences of a target text with a replacement text.4450 Argument | Type | Description | Default4451 ---------|------|-------------|---------4459 **Example:**4461 assert "Hello world".replace("world", "there") == "Hello there"4463 ```4464 ## Text.reversed4467 Text.reversed : func(text: Text -> Text)4468 ```4470 Return a text that has the grapheme clusters in reverse order.4472 Argument | Type | Description | Default4473 ---------|------|-------------|---------4479 **Example:**4481 assert "Abc".reversed() == "cbA"4483 ```4484 ## Text.right_pad4487 Text.right_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)4488 ```4490 Pad some text on the right side so it reaches a target width.4492 Argument | Type | Description | Default4493 ---------|------|-------------|---------4499 **Return:** Text with length at least `width`, with extra padding on the right as needed. If `pad` has length greater than 1, it may be partially repeated to reach the exact desired length.4502 **Example:**4504 assert "x".right_pad(5) == "x "4505 assert "x".right_pad(5, "ABC") == "xABCA"4507 ```4508 ## Text.slice4511 Text.slice : func(text: Text, from: Int = 1, to: Int = -1 -> Text)4512 ```4514 Get a slice of the text.4516 A negative index counts backwards from the end of the text, so `-1` refers to the last cluster, `-2` the second-to-last, etc. Slice ranges will be truncated to the length of the text.4518 Argument | Type | Description | Default4519 ---------|------|-------------|---------4527 **Example:**4529 assert "hello".slice(2, 3) == "el"4530 assert "hello".slice(to=-2) == "hell"4531 assert "hello".slice(from=2) == "ello"4533 ```4534 ## Text.split4537 Text.split : func(text: Text, delimiter: Text = "" -> [Text])4538 ```4540 Splits the text into a list of substrings based on exact matches of a delimiter.4542 To split based on a set of delimiters, use Text.split_any().4543 If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.4545 Argument | Type | Description | Default4546 ---------|------|-------------|---------4553 **Example:**4555 assert "one,two,,three".split(",") == ["one", "two", "", "three"]4556 assert "abc".split() == ["a", "b", "c"]4558 ```4559 ## Text.split_any4562 Text.split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> [Text])4563 ```4565 Splits the text into a list of substrings at one or more occurrences of a set of delimiter characters (grapheme clusters).4567 Splitting will occur on every place where one or more of the grapheme clusters in `delimiters` occurs.4568 To split based on an exact delimiter, use Text.split().4570 Argument | Type | Description | Default4571 ---------|------|-------------|---------4573 delimiters | `Text` | A text containing delimiters to use for splitting the text. | `" $\t\r\n"`4578 **Example:**4580 assert "one, two,,three".split_any(", ") == ["one", "two", "three"]4582 ```4583 ## Text.starts_with4586 Text.starts_with : func(text: Text, prefix: Text, remainder: &Text? = none -> Bool)4587 ```4591 Argument | Type | Description | Default4592 ---------|------|-------------|---------4595 remainder | `&Text?` | If non-none, this value will be set to the rest of the text after the prefix. If the prefix is not found, this value will be set to the original text. | `none`4600 **Example:**4602 assert "hello world".starts_with("hello") == yes4603 remainder : Text4604 assert "hello world".starts_with("hello", &remainder) == yes4605 assert remainder == " world"4607 ```4608 ## Text.title4611 Text.title : func(text: Text, language: Text = "C" -> Text)4612 ```4614 Converts the text to title case (capitalizing the first letter of each word).4616 Argument | Type | Description | Default4617 ---------|------|-------------|---------4624 **Example:**4626 assert "amélie".title() == "Amélie"4628 # In Turkish, uppercase "i" is "İ"4629 assert "i".title(language="tr_TR") == "İ"4631 ```4632 ## Text.to4635 Text.to : func(text: Text, last: Int -> Text)4636 ```4638 Get a slice of the text, ending at the given position.4640 A negative index counts backwards from the end of the text, so `-1` refers to the last cluster, `-2` the second-to-last, etc. Slice ranges will be truncated to the length of the text.4642 Argument | Type | Description | Default4643 ---------|------|-------------|---------4650 **Example:**4652 assert "goodbye".to(3) == "goo"4653 assert "goodbye".to(-2) == "goodby"4655 ```4656 ## Text.translate4659 Text.translate : func(text: Text, translations: {Text:Text} -> Text)4660 ```4662 Takes a table mapping target texts to their replacements and performs all the replacements in the table on the whole text. At each position, the first matching replacement is applied and the matching moves on to *after* the replacement text, so replacement text is not recursively modified. See Text.replace() for more information about replacement behavior.4664 Argument | Type | Description | Default4665 ---------|------|-------------|---------4669 **Return:** The text with all occurrences of the targets replaced with their corresponding replacement text.4672 **Example:**4674 text := "A <tag> & an ampersand".translate({4675 "&": "&",4676 "<": "<",4677 ">": ">",4678 '"': """,4679 "'": "'",4680 })4681 assert text == "A <tag> & an ampersand"4683 ```4684 ## Text.trim4687 Text.trim : func(text: Text, to_trim: Text = " $\t\r\n", left: Bool = yes, right: Bool = yes -> Text)4688 ```4690 Trims the given characters (grapheme clusters) from the left and/or right side of the text.4692 Argument | Type | Description | Default4693 ---------|------|-------------|---------4702 **Example:**4704 assert " x y z \n".trim() == "x y z"4705 assert "one,".trim(",") == "one"4706 assert " xyz ".trim(right=no) == "xyz "4708 ```4709 ## Text.upper4712 Text.upper : func(text: Text, language: Text = "C" -> Text)4713 ```4715 Converts all characters in the text to uppercase.4717 Argument | Type | Description | Default4718 ---------|------|-------------|---------4725 **Example:**4727 assert "amélie".upper() == "AMÉLIE"4729 # In Turkish, uppercase "i" is "İ"4730 assert "i".upper(language="tr_TR") == "İ"4732 ```4733 ## Text.utf164736 Text.utf16 : func(text: Text -> [Int16])4737 ```4739 Returns a list of Unicode code points for UTF16 encoding of the text.4741 Argument | Type | Description | Default4742 ---------|------|-------------|---------4748 **Example:**4750 assert "Åke".utf16() == [197, 107, 101]4751 assert "こんにちは世界".utf16() == [12371, 12435, 12395, 12385, 12399, 19990, 30028]4753 ```4754 ## Text.utf324757 Text.utf32 : func(text: Text -> [Int32])4758 ```4760 Returns a list of Unicode code points for UTF32 encoding of the text.4762 Argument | Type | Description | Default4763 ---------|------|-------------|---------4769 **Example:**4771 assert "Amélie".utf32() == [65, 109, 233, 108, 105, 101]4773 ```4774 ## Text.utf84777 Text.utf8 : func(text: Text -> [Byte])4778 ```4782 Argument | Type | Description | Default4783 ---------|------|-------------|---------4789 **Example:**4791 assert "Amélie".utf8() == [65, 109, 195, 169, 108, 105, 101]4793 ```4794 ## Text.width4797 Text.width : func(text: Text -> Int)4798 ```4800 Returns the display width of the text as seen in a terminal with appropriate font rendering. This is usually the same as the text's `.length`, but there are some characters like emojis that render wider than 1 cell.4802 This will not always be exactly accurate when your terminal's font rendering can't handle some unicode displaying correctly.4804 Argument | Type | Description | Default4805 ---------|------|-------------|---------4811 **Example:**4813 assert "Amélie".width() == 64814 assert "🤠".width() == 24816 ```4817 ## Text.without_prefix4820 Text.without_prefix : func(text: Text, prefix: Text -> Text)4821 ```4823 Returns the text with a given prefix removed (if present).4825 Argument | Type | Description | Default4826 ---------|------|-------------|---------4830 **Return:** A text without the given prefix (if present) or the unmodified text if the prefix is not present.4833 **Example:**4835 assert "foo:baz".without_prefix("foo:") == "baz"4836 assert "qux".without_prefix("foo:") == "qux"4838 ```4839 ## Text.without_suffix4842 Text.without_suffix : func(text: Text, suffix: Text -> Text)4843 ```4845 Returns the text with a given suffix removed (if present).4847 Argument | Type | Description | Default4848 ---------|------|-------------|---------4852 **Return:** A text without the given suffix (if present) or the unmodified text if the suffix is not present.4855 **Example:**4857 assert "baz.foo".without_suffix(".foo") == "baz"4858 assert "qux".without_suffix(".foo") == "qux"4860 ```