aboutsummaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-18 16:51:25 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-18 16:51:25 -0400
commita86eba55d7e26bc357735ccf190013b9346ccb4d (patch)
tree6be768661c0794e8319b76654a0a5ca8fb82fa42 /api
parent1e4f41bc28d781819a1a9d18d53abc0bbb8f5f21 (diff)
Add API docs
Diffstat (limited to 'api')
-rw-r--r--api/booleans.md60
-rw-r--r--api/integers.md338
-rw-r--r--api/nums.md1346
-rw-r--r--api/text.md753
4 files changed, 2497 insertions, 0 deletions
diff --git a/api/booleans.md b/api/booleans.md
new file mode 100644
index 00000000..86473b42
--- /dev/null
+++ b/api/booleans.md
@@ -0,0 +1,60 @@
+# Boolean Values
+
+Boolean values have the type `Bool` and can be either `yes` ("true") or `no`
+("false").
+
+# Boolean Functions
+
+This documentation provides details on boolean functions available in the API.
+
+## `from_text`
+
+**Description:**
+Converts a string representation of a boolean value into a boolean. Acceptable
+boolean values are case-insensitive variations of `yes`/`no`, `y`/`n`,
+`true`/`false`, `on`/`off`.
+
+**Usage:**
+```tomo
+from_text(text: Text, success: Bool = !&Bool) -> Bool
+```
+
+**Parameters:**
+
+- `text`: The string containing the boolean value.
+- `success`: If provided, this boolean value reference will be set to `yes` if the given text is a recognizable boolean value or `no` otherwise.
+
+**Returns:**
+`yes` if the string matches a recognized truthy boolean value; otherwise return `no`.
+
+**Example:**
+```tomo
+Boo.from_text("yes") // yes
+from_text("no") // no
+from_text("maybe") // !&Bool (default value)
+```
+
+---
+
+## `random`
+
+**Description:**
+Generates a random boolean value based on a specified probability.
+
+**Usage:**
+```tomo
+random(p: Float = 0.5) -> Bool
+```
+
+**Parameters:**
+
+- `p`: The probability (between `0` and `1`) of returning `yes`. Default is `0.5`.
+
+**Returns:**
+`yes` with probability `p`, and `no` with probability `1 - p`.
+
+**Example:**
+```tomo
+random(0.7) // yes (with 70% probability)
+random(0.3) // no (with 70% probability)
+```
diff --git a/api/integers.md b/api/integers.md
new file mode 100644
index 00000000..acbab60c
--- /dev/null
+++ b/api/integers.md
@@ -0,0 +1,338 @@
+# Integers
+
+Tomo has five types of integers:
+
+- `Int`: the default integer type, which uses an efficient tagged 29-bit
+ integer value for small numbers, and falls back to a bigint implementation
+ when values are too large to fit in 29-bits. The bigint implementation uses
+ the GNU MP library. These integers are fast for small numbers and guaranteed
+ to always be correct and never overflow.
+- `Int8`/`Int16`/`Int32`/`Int64`: Fixed-size integers that take up `N` bits.
+ These integers must be manually specified with their suffix (e.g. `5_i64`)
+ and are subject to overflowing. If an overflow occurs, a runtime error will
+ be raised.
+
+Conversion between integer types can be done by calling the target type as a
+function: `Int32(x)`. For fixed-width types, the conversion function also
+accepts a second parameter, `truncate`. If `truncate` is `no` (the default),
+conversion will create a runtime error if the value is too large to fit in the
+target type. If `truncate` is `yes`, then the resulting value will be a
+truncated form of the input value.
+
+Integers support the standard math operations (`x+y`, `x-y`, `x*y`, `x/y`) as
+well as powers/exponentiation (`x^y`), modulus (`x mod y` and `x mod1 y`), and
+bitwise operations: `x and y`, `x or y`, `x xor y`, `x << y`, and `x >> y`. The
+operators `and`, `or`, and `xor` are _bitwise_, not logical operators.
+
+# Integer Functions
+
+Each integer type has its own version of the following functions. Functions
+can be called either on the type itself: `Int.sqrt(x)` or as a method call:
+`x:sqrt()`. Method call syntax is preferred.
+
+## `format`
+
+**Description:**
+Formats an integer as a string with a specified number of digits.
+
+**Usage:**
+```tomo
+format(i: Int, digits: Int = 0) -> Text
+```
+
+**Parameters:**
+
+- `i`: The integer to be formatted.
+- `digits`: The minimum number of digits to which the integer should be padded. Default is `0`.
+
+**Returns:**
+A string representation of the integer, padded to the specified number of digits.
+
+**Example:**
+```tomo
+>> 42:format(digits=5)
+= "00042"
+```
+
+---
+
+## `hex`
+
+**Description:**
+Converts an integer to its hexadecimal representation.
+
+**Usage:**
+```tomo
+hex(i: Int, digits: Int = 0, uppercase: Bool = yes, prefix: Bool = yes) -> Text
+```
+
+**Parameters:**
+
+- `i`: The integer to be converted.
+- `digits`: The minimum number of digits in the output string. Default is `0`.
+- `uppercase`: Whether to use uppercase letters for hexadecimal digits. Default is `yes`.
+- `prefix`: Whether to include a "0x" prefix. Default is `yes`.
+
+**Returns:**
+The hexadecimal string representation of the integer.
+
+**Example:**
+```tomo
+>> 255:hex(digits=4, uppercase=yes, prefix=yes)
+= "0x00FF"
+```
+
+---
+
+## `octal`
+
+**Description:**
+Converts an integer to its octal representation.
+
+**Usage:**
+```tomo
+octal(i: Int, digits: Int = 0, prefix: Bool = yes) -> Text
+```
+
+**Parameters:**
+
+- `i`: The integer to be converted.
+- `digits`: The minimum number of digits in the output string. Default is `0`.
+- `prefix`: Whether to include a "0o" prefix. Default is `yes`.
+
+**Returns:**
+The octal string representation of the integer.
+
+**Example:**
+```tomo
+>> 64:octal(digits=4, prefix=yes)
+= "0o0100"
+```
+
+---
+
+## `random`
+
+**Description:**
+Generates a random integer between the specified minimum and maximum values.
+
+**Usage:**
+```tomo
+random(min: Int, max: Int) -> Int
+```
+
+**Parameters:**
+
+- `min`: The minimum value of the range.
+- `max`: The maximum value of the range.
+
+**Returns:**
+A random integer between `min` and `max` (inclusive).
+
+**Example:**
+```tomo
+>> Int.random(1, 100)
+= 47
+```
+
+---
+
+## `from_text`
+
+**Description:**
+Converts a text representation of an integer into an integer.
+
+**Usage:**
+```tomo
+from_text(text: Text, the_rest: Text = "!&Text") -> Int
+```
+
+**Parameters:**
+
+- `text`: The string containing the integer.
+- `the_rest`: If non-null, this pointer will be set to point to any unparseable text after the integer.
+
+**Returns:**
+The integer represented by the string.
+
+**Example:**
+```tomo
+>> from_text("123")
+= 123
+>> from_text("0xFF")
+= 255
+```
+
+---
+
+## `to`
+
+**Description:**
+Creates an inclusive range of integers between the specified start and end values.
+
+**Usage:**
+```tomo
+to(from: Int, to: Int) -> Range
+```
+
+**Parameters:**
+
+- `from`: The starting value of the range.
+- `to`: The ending value of the range.
+
+**Returns:**
+A range object representing all integers from `from` to `to` (inclusive).
+
+**Example:**
+```tomo
+>> 1:to(5)
+= Range(first=1, last=5, step=1)
+```
+
+---
+
+## `abs`
+
+**Description:**
+Calculates the absolute value of an integer.
+
+**Usage:**
+```tomo
+abs(x: Int) -> Int
+```
+
+**Parameters:**
+
+- `x`: The integer whose absolute value is to be calculated.
+
+**Returns:**
+The absolute value of `x`.
+
+**Example:**
+```tomo
+>> -10:abs()
+= 10
+```
+
+---
+
+## `sqrt`
+
+**Description:**
+Calculates the square root of an integer.
+
+**Usage:**
+```tomo
+sqrt(x: Int) -> Int
+```
+
+**Parameters:**
+
+- `x`: The integer whose square root is to be calculated.
+
+**Returns:**
+The integer part of the square root of `x`.
+
+**Example:**
+```tomo
+>> 16:sqrt()
+= 4
+>> 17:sqrt()
+= 4
+```
+
+---
+
+## `is_prime`
+
+**Description:**
+Determines if an integer is a prime number.
+
+**Note:**
+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.
+
+**Usage:**
+```tomo
+is_prime(x: Int, reps: Int = 50) -> Bool
+```
+
+**Parameters:**
+
+- `x`: The integer to be checked.
+- `reps`: The number of repetitions for primality tests. Default is `50`.
+
+**Returns:**
+`yes` if `x` is a prime number, `no` otherwise.
+
+**Example:**
+```tomo
+>> 7:is_prime()
+= yes
+>> 6:is_prime()
+= no
+```
+
+---
+
+## `next_prime`
+
+**Description:**
+Finds the next prime number greater than the given integer.
+
+**Note:**
+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.
+
+**Usage:**
+```tomo
+next_prime(x: Int) -> Int
+```
+
+**Parameters:**
+
+- `x`: The integer after which to find the next prime.
+
+**Returns:**
+The next prime number greater than `x`.
+
+**Example:**
+```tomo
+11:next_prime() // 13
+```
+
+---
+
+## `prev_prime`
+
+**Description:**
+Finds the previous prime number less than the given integer.
+If there is no previous prime number (i.e. if a number less than `2` is
+provided), then the function will create a runtime error.
+
+**Note:**
+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.
+
+**Usage:**
+```tomo
+prev_prime(x: Int) -> Int
+```
+
+**Parameters:**
+
+- `x`: The integer before which to find the previous prime.
+
+**Returns:**
+The previous prime number less than `x`.
+
+**Example:**
+```tomo
+11:prev_prime() // 7
+```
diff --git a/api/nums.md b/api/nums.md
new file mode 100644
index 00000000..5f28b1a3
--- /dev/null
+++ b/api/nums.md
@@ -0,0 +1,1346 @@
+# Nums
+
+Tomo has two floating point number types: `Num` (64-bit, AKA `double`) and
+`Num32` (32-bit, AKA `float`). Num literals can have a decimal point (e.g.
+`5.`), a scientific notation suffix (e.g. `1e8`) or a percent sign. Numbers
+that end in a percent sign are divided by 100 at compile time (i.e. `5% ==
+0.05`).
+
+Nums support the standard math operations (`x+y`, `x-y`, `x*y`, `x/y`) as well as
+powers/exponentiation (`x^y`) and modulus (`x mod y` and `x mod1 y`).
+
+# Num Functions
+
+Each Num type has its own version of the following functions. Functions can be
+called either on the type itself: `Num.sqrt(x)` or as a method call:
+`x:sqrt()`. Method call syntax is preferred.
+
+## Constants
+
+- **`1_PI`**: \( \frac{1}{\pi} \)
+- **`2_PI`**: \( 2 \times \pi \)
+- **`2_SQRTPI`**: \( 2 \times \sqrt{\pi} \)
+- **`E`**: Base of natural logarithms (\( e \))
+- **`INF`**: Positive infinity
+- **`LN10`**: Natural logarithm of 10
+- **`LN2`**: Natural logarithm of 2
+- **`LOG2E`**: Logarithm base 2 of \( e \)
+- **`PI`**: Pi (\( \pi \))
+- **`PI_2`**: \( \frac{\pi}{2} \)
+- **`PI_4`**: \( \frac{\pi}{4} \)
+- **`SQRT1_2`**: \( \sqrt{\frac{1}{2}} \)
+- **`SQRT2`**: \( \sqrt{2} \)
+- **`TAU`**: Tau (\( 2 \times \pi \))
+
+## Functions
+
+### `abs`
+
+**Description:**
+Calculates the absolute value of a number.
+
+**Usage:**
+```tomo
+abs(n: Num) -> Num
+```
+
+**Parameters:**
+
+- `n`: The number whose absolute value is to be computed.
+
+**Returns:**
+The absolute value of `n`.
+
+**Example:**
+```tomo
+>> -3.5:abs()
+= 3.5
+```
+
+---
+
+### `acos`
+
+**Description:**
+Computes the arc cosine of a number.
+
+**Usage:**
+```tomo
+acos(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the arc cosine is to be calculated.
+
+**Returns:**
+The arc cosine of `x` in radians.
+
+**Example:**
+```tomo
+>> 0.0:acos() // -> (π/2)
+= 1.5708
+```
+
+---
+
+### `acosh`
+
+**Description:**
+Computes the inverse hyperbolic cosine of a number.
+
+**Usage:**
+```tomo
+acosh(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the inverse hyperbolic cosine is to be calculated.
+
+**Returns:**
+The inverse hyperbolic cosine of `x`.
+
+**Example:**
+```tomo
+>> 1.0:acosh()
+= 0
+```
+
+---
+
+### `asin`
+
+**Description:**
+Computes the arc sine of a number.
+
+**Usage:**
+```tomo
+asin(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the arc sine is to be calculated.
+
+**Returns:**
+The arc sine of `x` in radians.
+
+**Example:**
+```tomo
+>> 0.5:asin() // -> (π/6)
+= 0.5236
+```
+
+---
+
+### `asinh`
+
+**Description:**
+Computes the inverse hyperbolic sine of a number.
+
+**Usage:**
+```tomo
+asinh(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the inverse hyperbolic sine is to be calculated.
+
+**Returns:**
+The inverse hyperbolic sine of `x`.
+
+**Example:**
+```tomo
+>> 0.0:asinh()
+= 0
+```
+
+---
+
+### `atan2`
+
+**Description:**
+Computes the arc tangent of the quotient of two numbers.
+
+**Usage:**
+```tomo
+atan2(x: Num, y: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The numerator.
+- `y`: The denominator.
+
+**Returns:**
+The arc tangent of `x/y` in radians.
+
+**Example:**
+```tomo
+>> Num.atan2(1, 1) // -> (π/4)
+= 0.7854
+```
+
+---
+
+### `atan`
+
+**Description:**
+Computes the arc tangent of a number.
+
+**Usage:**
+```tomo
+atan(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the arc tangent is to be calculated.
+
+**Returns:**
+The arc tangent of `x` in radians.
+
+**Example:**
+```tomo
+>> 1.0:atan() // -> (π/4)
+= 0.7854
+```
+
+---
+
+### `atanh`
+
+**Description:**
+Computes the inverse hyperbolic tangent of a number.
+
+**Usage:**
+```tomo
+atanh(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the inverse hyperbolic tangent is to be calculated.
+
+**Returns:**
+The inverse hyperbolic tangent of `x`.
+
+**Example:**
+```tomo
+>> 0.5:atanh()
+= 0.5493
+```
+
+---
+
+### `cbrt`
+
+**Description:**
+Computes the cube root of a number.
+
+**Usage:**
+```tomo
+cbrt(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the cube root is to be calculated.
+
+**Returns:**
+The cube root of `x`.
+
+**Example:**
+```tomo
+>> 27.0:cbrt()
+= 3
+```
+
+---
+
+### `ceil`
+
+**Description:**
+Rounds a number up to the nearest integer.
+
+**Usage:**
+```tomo
+ceil(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number to be rounded up.
+
+**Returns:**
+The smallest integer greater than or equal to `x`.
+
+**Example:**
+```tomo
+>> 3.2:ceil()
+= 4
+```
+
+---
+
+### `copysign`
+
+**Description:**
+Copies the sign of one number to another.
+
+**Usage:**
+```tomo
+copysign(x: Num, y: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number whose magnitude will be copied.
+- `y`: The number whose sign will be copied.
+
+**Returns:**
+A number with the magnitude of `x` and the sign of `y`.
+
+**Example:**
+```tomo
+>> 3.0:copysign(-1)
+= -3
+```
+
+---
+
+### `cos`
+
+**Description:**
+Computes the cosine of a number (angle in radians).
+
+**Usage:**
+```tomo
+cos(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The angle in radians.
+
+**Returns:**
+The cosine of `x`.
+
+**Example:**
+```tomo
+>> 0.0:cos()
+= 1
+```
+
+---
+
+### `cosh`
+
+**Description:**
+Computes the hyperbolic cosine of a number.
+
+**Usage:**
+```tomo
+cosh(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the hyperbolic cosine is to be calculated.
+
+**Returns:**
+The hyperbolic cosine of `x`.
+
+**Example:**
+```tomo
+>> 0.0:cosh()
+= 1
+```
+
+---
+
+### `erf`
+
+**Description:**
+Computes the error function of a number.
+
+**Usage:**
+```tomo
+erf(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the error function is to be calculated.
+
+**Returns:**
+The error function of `x`.
+
+**Example:**
+```tomo
+>> 0.0:erf()
+= 0
+```
+
+---
+
+### `erfc`
+
+**Description:**
+Computes the complementary error function of a number.
+
+**Usage:**
+```tomo
+erfc(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the complementary error function is to be calculated.
+
+**Returns:**
+The complementary error function of `x`.
+
+**Example:**
+```tomo
+>> 0.0:erfc()
+= 1
+```
+
+---
+
+### `exp2`
+
+**Description:**
+Computes \( 2^x \) for a number.
+
+**Usage:**
+```tomo
+exp2(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The exponent.
+
+**Returns:**
+The value of \( 2^x \).
+
+**Example:**
+```tomo
+>> 3.0:exp2()
+= 8
+```
+
+---
+
+### `exp`
+
+**Description:**
+Computes the exponential function \( e^x \) for a number.
+
+**Usage:**
+```tomo
+exp(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The exponent.
+
+**Returns:**
+The value of \( e^x \).
+
+**Example:**
+```tomo
+>> 1.0:exp()
+= 2.7183
+```
+
+---
+
+### `expm1`
+
+**Description:**
+Computes \( e^x - 1 \) for a number.
+
+**Usage:**
+```tomo
+expm1(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The exponent.
+
+**Returns:**
+The value of \( e^x - 1 \).
+
+**Example:**
+```tomo
+>> 1.0:expm1()
+= 1.7183
+```
+
+---
+
+### `fdim`
+
+**Description:**
+Computes the positive difference between two numbers.
+
+**Usage:**
+```tomo
+fdim(x: Num, y: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The first number.
+- `y`: The second number.
+
+**Returns:**
+The positive difference \( \max(0, x - y) \).
+
+**Example:**
+```tomo
+fd
+
+>> 5.0:fdim(3)
+= 2
+```
+
+---
+
+### `floor`
+
+**Description:**
+Rounds a number down to the nearest integer.
+
+**Usage:**
+```tomo
+floor(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number to be rounded down.
+
+**Returns:**
+The largest integer less than or equal to `x`.
+
+**Example:**
+```tomo
+>> 3.7:floor()
+= 3
+```
+
+---
+
+### `format`
+
+**Description:**
+Formats a number as a string with a specified precision.
+
+**Usage:**
+```tomo
+format(n: Num, precision: Int = 0) -> Text
+```
+
+**Parameters:**
+
+- `n`: The number to be formatted.
+- `precision`: The number of decimal places. Default is `0`.
+
+**Returns:**
+A string representation of the number with the specified precision.
+
+**Example:**
+```tomo
+>> 3.14159:format(precision=2)
+= "3.14"
+```
+
+---
+
+### `from_text`
+
+**Description:**
+Converts a string representation of a number into a floating-point number.
+
+**Usage:**
+```tomo
+from_text(text: Text, the_rest: Text = "!&Text") -> Num
+```
+
+**Parameters:**
+
+- `text`: The string containing the number.
+- `the_rest`: A string indicating what to return if the conversion fails. Default is `"!&Text"`.
+
+**Returns:**
+The number represented by the string.
+
+**Example:**
+```tomo
+>> Num.from_text("3.14")
+= 3.14
+>> Num.from_text("1e3")
+= 1000
+```
+
+---
+
+### `hypot`
+
+**Description:**
+Computes the Euclidean norm, \( \sqrt{x^2 + y^2} \), of two numbers.
+
+**Usage:**
+```tomo
+hypot(x: Num, y: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The first number.
+- `y`: The second number.
+
+**Returns:**
+The Euclidean norm of `x` and `y`.
+
+**Example:**
+```tomo
+>> Num.hypot(3, 4)
+= 5
+```
+
+---
+
+### `isfinite`
+
+**Description:**
+Checks if a number is finite.
+
+**Usage:**
+```tomo
+isfinite(n: Num) -> Bool
+```
+
+**Parameters:**
+
+- `n`: The number to be checked.
+
+**Returns:**
+`yes` if `n` is finite, `no` otherwise.
+
+**Example:**
+```tomo
+>> 1.0:isfinite()
+= yes
+>> Num.INF:isfinite()
+= no
+```
+
+---
+
+### `isinf`
+
+**Description:**
+Checks if a number is infinite.
+
+**Usage:**
+```tomo
+isinf(n: Num) -> Bool
+```
+
+**Parameters:**
+
+- `n`: The number to be checked.
+
+**Returns:**
+`yes` if `n` is infinite, `no` otherwise.
+
+**Example:**
+```tomo
+>> Num.INF:isinf()
+= yes
+>> 1.0:isinf()
+= no
+```
+
+---
+
+### `isnan`
+
+**Description:**
+Checks if a number is NaN (Not a Number).
+
+**Usage:**
+```tomo
+isnan(n: Num) -> Bool
+```
+
+**Parameters:**
+
+- `n`: The number to be checked.
+
+**Returns:**
+`yes` if `n` is NaN, `no` otherwise.
+
+**Example:**
+```tomo
+>> Num.nan():isnan()
+= yes
+>> 1.0:isnan()
+= no
+```
+
+---
+
+### `j0`
+
+**Description:**
+Computes the Bessel function of the first kind of order 0.
+
+**Usage:**
+```tomo
+j0(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the Bessel function is to be calculated.
+
+**Returns:**
+The Bessel function of the first kind of order 0 of `x`.
+
+**Example:**
+```tomo
+>> 0.0:j0()
+= 1
+```
+
+---
+
+### `j1`
+
+**Description:**
+Computes the Bessel function of the first kind of order 1.
+
+**Usage:**
+```tomo
+j1(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the Bessel function is to be calculated.
+
+**Returns:**
+The Bessel function of the first kind of order 1 of `x`.
+
+**Example:**
+```tomo
+>> 0.0:j1()
+= 0
+```
+
+---
+
+### `log10`
+
+**Description:**
+Computes the base-10 logarithm of a number.
+
+**Usage:**
+```tomo
+log10(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the base-10 logarithm is to be calculated.
+
+**Returns:**
+The base-10 logarithm of `x`.
+
+**Example:**
+```tomo
+>> 100.0:log10()
+= 2
+```
+
+---
+
+### `log1p`
+
+**Description:**
+Computes \( \log(1 + x) \) for a number.
+
+**Usage:**
+```tomo
+log1p(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which \( \log(1 + x) \) is to be calculated.
+
+**Returns:**
+The value of \( \log(1 + x) \).
+
+**Example:**
+```tomo
+>> 1.0:log1p()
+= 0.6931
+```
+
+---
+
+### `log2`
+
+**Description:**
+Computes the base-2 logarithm of a number.
+
+**Usage:**
+```tomo
+log2(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the base-2 logarithm is to be calculated.
+
+**Returns:**
+The base-2 logarithm of `x`.
+
+**Example:**
+```tomo
+>> 8.0:log2()
+= 3
+```
+
+---
+
+### `log`
+
+**Description:**
+Computes the natural logarithm (base \( e \)) of a number.
+
+**Usage:**
+```tomo
+log(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the natural logarithm is to be calculated.
+
+**Returns:**
+The natural logarithm of `x`.
+
+**Example:**
+```tomo
+>> Num.E:log()
+= 1
+```
+
+---
+
+### `logb`
+
+**Description:**
+Computes the binary exponent (base-2 logarithm) of a number.
+
+**Usage:**
+```tomo
+logb(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the binary exponent is to be calculated.
+
+**Returns:**
+The binary exponent of `x`.
+
+**Example:**
+```tomo
+>> 8.0:logb()
+= 3
+```
+
+---
+
+### `mix`
+
+**Description:**
+Interpolates between two numbers based on a given amount.
+
+**Usage:**
+```tomo
+mix(amount: Num, x: Num, y: Num) -> Num
+```
+
+**Parameters:**
+
+- `amount`: The interpolation factor (between `0` and `1`).
+- `x`: The starting number.
+- `y`: The ending number.
+
+**Returns:**
+The interpolated number between `x` and `y` based on `amount`.
+
+**Example:**
+```tomo
+>> 0.5:mix(10, 20)
+= 15
+>> 0.25:mix(10, 20)
+= 12.5
+```
+
+---
+
+### `nan`
+
+**Description:**
+Generates a NaN (Not a Number) value.
+
+**Usage:**
+```tomo
+nan(tag: Text = "") -> Num
+```
+
+**Parameters:**
+
+- `tag`: An optional tag to describe the NaN. Default is an empty string.
+
+**Returns:**
+A NaN value.
+
+**Example:**
+```tomo
+>> Num.nan()
+= NaN
+```
+
+---
+
+### `near`
+
+**Description:**
+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.
+
+**Usage:**
+```tomo
+near(x: Num, y: Num, ratio: Num = 1e-9, min_epsilon: Num = 1e-9) -> Bool
+```
+
+**Parameters:**
+
+- `x`: The first number.
+- `y`: The second number.
+- `ratio`: The relative tolerance. Default is `1e-9`.
+- `min_epsilon`: The absolute tolerance. Default is `1e-9`.
+
+**Returns:**
+`yes` if `x` and `y` are approximately equal within the specified tolerances, `no` otherwise.
+
+**Example:**
+```tomo
+>> 1.0:near(1.000000001)
+= yes
+
+>> 100.0:near(110, ratio=0.1)
+= yes
+
+>> 5.0:near(5.1, min_epsilon=0.1)
+= yes
+```
+
+---
+
+### `nextafter`
+
+**Description:**
+Computes the next representable value after a given number towards a specified direction.
+
+**Usage:**
+```tomo
+nextafter(x: Num, y: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The starting number.
+- `y`: The direction towards which to find the next representable value.
+
+**Returns:**
+The next representable value after `x` in the direction of `y`.
+
+**Example:**
+```tomo
+>> 1.0:nextafter(1.1)
+= 1.0000000000000002
+```
+
+---
+
+### `random`
+
+**Description:**
+Generates a random floating-point number.
+
+**Usage:**
+```tomo
+random() -> Num
+```
+
+**Parameters:**
+None
+
+**Returns:**
+A random floating-point number between 0 and 1.
+
+**Example:**
+```tomo
+>> Num.random()
+= 0.4521
+```
+
+---
+
+### `rint`
+
+**Description:**
+Rounds a number to the nearest integer, with ties rounded to the nearest even integer.
+
+**Usage:**
+```tomo
+rint(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number to be rounded.
+
+**Returns:**
+The nearest integer value of `x`.
+
+**Example:**
+```tomo
+>> 3.5:rint()
+= 4
+>> 2.5:rint()
+= 2
+```
+
+---
+
+### `round`
+
+**Description:**
+Rounds a number to the nearest whole number integer.
+
+**Usage:**
+```tomo
+round(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number to be rounded.
+
+**Returns:**
+The nearest integer value of `x`.
+
+**Example:**
+```tomo
+>> 2.3:round()
+= 2
+>> 2.7:round()
+= 3
+```
+
+---
+
+### `scientific`
+
+**Description:**
+Formats a number in scientific notation with a specified precision.
+
+**Usage:**
+```tomo
+scientific(n: Num, precision: Int = 0) -> Text
+```
+
+**Parameters:**
+
+- `n`: The number to be formatted.
+- `precision`: The number of decimal places. Default is `0`.
+
+**Returns:**
+A string representation of the number in scientific notation with the specified precision.
+
+**Example:**
+```tomo
+>> 12345.6789:scientific(precision=2)
+= "1.23e+04"
+```
+
+---
+
+### `significand`
+
+**Description:**
+Extracts the significand (or mantissa) of a number.
+
+**Usage:**
+```tomo
+significand(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number from which to extract the significand.
+
+**Returns:**
+The significand of `x`.
+
+**Example:**
+```tomo
+>> 1234.567:significand()
+= 0.1234567
+```
+
+---
+
+### `sin`
+
+**Description:**
+Computes the sine of a number (angle in radians).
+
+**Usage:**
+```tomo
+sin(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The angle in radians.
+
+**Returns:**
+The sine of `x`.
+
+**Example:**
+```tomo
+>> 0.0:sin()
+= 0
+```
+
+---
+
+### `sinh`
+
+**Description:**
+Computes the hyperbolic sine of a number.
+
+**Usage:**
+```tomo
+sinh(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the hyperbolic sine is to be calculated.
+
+**Returns:**
+The hyperbolic sine of `x`.
+
+**Example:**
+```tomo
+>> 0.0:sinh()
+= 0
+```
+
+---
+
+### `sqrt`
+
+**Description:**
+Computes the square root of a number.
+
+**Usage:**
+```tomo
+sqrt(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the square root is to be calculated.
+
+**Returns:**
+The square root of `x`.
+
+**Example:**
+```tomo
+>> 16.0:sqrt()
+= 4
+```
+
+---
+
+### `tan`
+
+**Description:**
+Computes the tangent of a number (angle in radians).
+
+**Usage:**
+```tomo
+tan(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The angle in radians.
+
+**Returns:**
+The tangent of `x`.
+
+**Example:**
+```tomo
+>> 0.0:tan()
+= 0
+```
+
+---
+
+### `tanh`
+
+**Description:**
+Computes the hyperbolic tangent of a number.
+
+**Usage:**
+```tomo
+tanh(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the hyperbolic tangent is to be calculated.
+
+**Returns:**
+The hyperbolic tangent of `x`.
+
+**Example:**
+```tomo
+>> 0.0:tanh()
+= 0
+```
+
+---
+
+### `tgamma`
+
+**Description:**
+Computes the gamma function of a number.
+
+**Usage:**
+```tomo
+tgamma(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the gamma function is to be calculated.
+
+**Returns:**
+The gamma function of `x`.
+
+**Example:**
+```tomo
+>> 1.0:tgamma()
+= 1
+```
+
+---
+
+### `trunc`
+
+**Description:**
+Truncates a number to the nearest integer towards zero.
+
+**Usage:**
+```tomo
+trunc(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number to be truncated.
+
+**Returns:**
+The integer part of `x` towards zero.
+
+**Example:**
+```tomo
+>> 3.7:trunc()
+= 3
+>> (-3.7):trunc()
+= -3
+```
+
+---
+
+### `y0`
+
+**Description:**
+Computes the Bessel function of the second kind of order 0.
+
+**Usage:**
+```tomo
+y0(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the Bessel function is to be calculated.
+
+**Returns:**
+The Bessel function of the second kind of order 0 of `x`.
+
+**Example:**
+```tomo
+>> 1.0:y0()
+= -0.7652
+```
+
+---
+
+### `y1`
+
+**Description:**
+Computes the Bessel function of the second kind of order 1.
+
+**Usage:**
+```tomo
+y1(x: Num) -> Num
+```
+
+**Parameters:**
+
+- `x`: The number for which the Bessel function is to be calculated.
+
+**Returns:**
+The Bessel function of the second kind of order 1 of `x`.
+
+**Example:**
+```tomo
+>> 1.0:y1()
+= 0.4401
+```
diff --git a/api/text.md b/api/text.md
new file mode 100644
index 00000000..4aeafc59
--- /dev/null
+++ b/api/text.md
@@ -0,0 +1,753 @@
+# Text
+
+`Text` is Tomo's datatype to represent text. The name `Text` is used instead of
+"string" because Tomo represents text as an immutable UTF-8-encoded value that
+uses the Boehm Cord library for efficient storage and concatenation. These are
+_not_ C-style NULL-terminated character arrays. GNU libunistring is used for
+full Unicode functionality (grapheme cluster counts, capitalization, etc.).
+
+## Syntax
+
+Text has a flexible syntax designed to make it easy to hold values from
+different languages without the need to have lots of escape sequences and
+without using printf-style string formatting.
+
+```
+// Basic text:
+str := "Hello world"
+str2 := 'Also text'
+str3 := `Backticks too`
+```
+
+## Line Splits
+
+Long text can be split across multiple lines by having two or more dots at the
+start of a new line on the same indentation level that started the text:
+
+```
+str := "This is a long
+....... line that is split in code"
+```
+
+## Multi-line Text
+
+Multi-line text has indented (i.e. at least one tab more than the start of the
+text) text inside quotation marks. The leading and trailing newline are
+ignored:
+
+```
+multi_line := "
+ This text has multiple lines.
+ Line two.
+
+ You can split a line
+.... using two or more dots to make an elipsis.
+
+ Remember to include whitespace after the elipsis if desired.
+
+ Or don't if you're splitting a long word like supercalifragilisticexpia
+....lidocious
+
+ This text is indented by one level in the text
+
+ "quotes" are ignored unless they're at the same indentation level as the
+.... start of the text.
+
+ The end (no newline after this).
+"
+```
+
+## Text Interpolations
+
+Inside double quoted text, you can use a dollar sign (`$`) to insert an
+expression that you want converted to text. This is called text interpolation:
+
+```
+// Interpolation:
+my_var := 5
+str := "My var is $my_var!"
+// Equivalent to "My var is 5!"
+
+// Using parentheses:
+str := "Sum: $(1 + 2)"
+// equivalent to "Sum: 3"
+```
+
+Single-quoted text does not have interpolations:
+
+```
+// No interpolation here:
+str := 'Sum: $(1 + 2)'
+```
+
+## Text Escapes
+
+Unlike other languages, backslash is *not* a special character inside of text.
+For example, `"x\ny"` has the characters `x`, `\`, `n`, `y`, not a newline.
+Instead, a series of character escapes act as complete text literals without
+quotation marks:
+
+```
+newline := \n
+crlf := \r\n
+quote := \"
+```
+
+These text literals can be used as interpolation values with or without
+parentheses, depending on which you find more readable:
+
+```
+two_lines := "one$(\n)two"
+has_quotes := "some $\"quotes$\" here"
+```
+
+However, in general it is best practice to use multi-line text to avoid these problems:
+
+```
+str := "
+ This has
+ multiple lines and "quotes" too!
+"
+```
+
+### Multi-line Text
+
+There are two reasons for text to span multiple lines in code: either you
+have text that contains newlines and you want to represent it without `\n`
+escapes, or you have a long single-line text that you want to split across
+multiple lines for readability. To support this, you can use newlines inside of
+text with indentation-sensitivity. For splitting long lines, use two or more
+"."s at the same indentation level as the start of the text literal:
+
+```
+single_line := "This is a long text that
+... spans multiple lines"
+```
+For text that contains newlines, you may put multiple indented lines inside
+the quotes:
+
+```
+multi_line := "
+ line one
+ line two
+ this line is indented
+ last line
+"
+```
+
+Text may only end on lines with the same indentation as the starting quote
+and nested quotes are ignored:
+
+```
+multi_line := "
+ Quotes in indented regions like this: " don't count
+"
+```
+
+If there is a leading or trailing newline, it is ignored and not included in
+the text.
+
+```
+str := "
+ one line
+"
+
+>>> str == "one line"
+=== yes
+```
+
+Additional newlines *are* counted though:
+
+```
+str := "
+
+ blank lines
+
+"
+
+>>> str == "{\n}blank lines{\n}"
+```
+
+### Customizable `$`-Text
+
+Sometimes you might need to use a lot of literal `$`s or quotation marks in
+text. In such cases, you can use the more customizable form of text. The
+customizable form lets you explicitly specify which character to use for
+interpolation and which characters to use for delimiting the text.
+
+The first character after the `$` is the custom interpolation character, which
+can be any of the following symbols: `~!@#$%^&*+=\?`. If none of these
+characters is used, the default interpolation character is `$`. Since this is
+the default, you can disable interpolation altogether by using `$` here (i.e. a
+double `$$`).
+
+The next thing in a customizable text is the character used to delimit the
+text. The text delimiter can be any of the following symbols: `` "'`|/;([{< ``
+If the text delimiter is one of `([{<`, then the text will continue until a
+matching `)]}>` is found, not terminating unless the delimiters are balanced
+(i.e. nested pairs of delimiters are considered part of the text).
+
+Here are some examples:
+
+```
+$"Equivalent to normal text with dollar interps: $(1 + 2)"
+$@"The same, but the AT symbol interpolates: @(1 + 2)"
+$$"No interpolation here, $ is just a literal character"
+$|This text is pipe-delimited, so it can have "quotes" and 'single quotes' and interpolates with dollar sign: $(1+2)|
+$(This text is parens-delimited, so you can have (nested) parens without ending the text)
+$=[This text is square-bracket delimited [which can be nested] and uses equals for interps: =(1 + 2)]
+$@/look ma, regex literals!/
+```
+
+When text is delimited by matching pairs (`()`, `[]`, `{}`, or `<>`), they
+can only be closed by a matched closing character at the same indentation
+level, ignoring nested pairs:
+
+```
+$$(Inside parens, you can have (nested ()) parens no problem)
+$$"But only (), [], {}, and <> are matching pairs, you can't have nested quotes"
+$$(
+ When indented, an unmatched ) won't close the text
+ An unmatched ( won't mess things up either
+ Only matching pairs on the same indentation level are counted:
+)
+$$(Multi-line text with nested (parens) and
+.. line continuation)
+```
+
+As a special case, when you use the same character for interpolation and text
+delimiting, no interpolations are allowed:
+
+```
+plain := $""This text has {no interpolations}!"
+```
+
+**Note:** Normal doubly quoted text with no dollar sign (e.g. `"foo"`) are a
+shorthand for `${}"foo"`. Singly quoted text with no dollar sign (e.g.
+`'foo'`) are shorthand for `$''foo'`.
+
+## Operations
+
+### Concatenation
+
+Concatenation in the typical case is an O(1) operation: `"{x}{y}"` or `x ++ y`.
+
+Because text concatenation is typically an O(1) operation, there is no need for
+a separate "string builder" class in the language and no need to use an array
+of text fragments.
+
+### Text Length
+
+Text length is an ambiguous term in the context of UTF-8 text. There are
+several possible meanings, so each of these meanings is split into a separate
+method:
+
+- Number of grapheme clusters: `text:num_clusters()`. This is probably what
+ you want to use, since it corresponds to the everyday notion of "letters".
+- Size in bytes: `text:num_bytes()`
+- Number of unicode codepoints: `text:num_codepoints()` (you probably want to
+ use clusters, not codepoints in most applications)
+
+Since the typical user expectation is that text length refers to "letters,"
+the `#` length operator returns the number of grapheme clusters, which is the
+closest unicode equivalent to "letters."
+
+### Iteration
+
+Iteration is *not* supported for text because of the ambiguity between bytes,
+codepoints, and grapheme clusters. It is instead recommended that you
+explicitly iterate over bytes, codepoints, graphemes, words, lines, etc:
+
+### Equality, Comparison, and Hashing
+
+All text is compared and hashed using unicode normalization. Unicode provides
+several different ways to represent the same text. For example, the single
+codepoint `U+E9` (latin small e with accent) is rendered the same as the two
+code points `U+65 U+301` (latin small e, acute combining accent) and has an
+equivalent linguistic meaning. These are simply different ways to represent the
+same "letter." In order to make it easy to write correct code that takes this
+into account, Tomo uses unicode normalization for all text comparisons and
+hashing. Normalization does the equivalent of converting text to a canonical
+form before performing comparisons or hashing. This means that if a table is
+created that has text with the codepoint `U+E9` as a key, then a lookup with
+the same text but with `U+65 U+301` instead of `U+E9` will still succeed in
+finding the value because the two texts are equivalent under normalization.
+
+
+# Text Functions
+
+## `as_c_string`
+
+**Description:**
+Converts a `Text` value to a C-style string.
+
+**Usage:**
+```markdown
+as_c_string(text: Text) -> CString
+```
+
+**Parameters:**
+
+- `text`: The text to be converted to a C-style string.
+
+**Returns:**
+A C-style string (`CString`) representing the text.
+
+**Example:**
+```markdown
+>> "Hello":as_c_string()
+= CString("Hello")
+```
+
+---
+
+## `bytes`
+
+**Description:**
+Converts a `Text` value to an array of bytes.
+
+**Usage:**
+```markdown
+bytes(text: Text) -> [Int8]
+```
+
+**Parameters:**
+
+- `text`: The text to be converted to bytes.
+
+**Returns:**
+An array of bytes (`[Int8]`) representing the text.
+
+**Example:**
+```markdown
+>> "Amélie":bytes()
+= [65_i8, 109_i8, 101_i8, -52_i8, -127_i8, 108_i8, 105_i8, 101_i8]
+```
+
+---
+
+## `character_names`
+
+**Description:**
+Returns a list of character names from the text.
+
+**Usage:**
+```markdown
+character_names(text: Text) -> [Text]
+```
+
+**Parameters:**
+
+- `text`: The text from which to extract character names.
+
+**Returns:**
+A list of character names (`[Text]`).
+
+**Example:**
+```markdown
+>> "Amélie":character_names()
+= ["LATIN CAPITAL LETTER A", "LATIN SMALL LETTER M", "LATIN SMALL LETTER E", "COMBINING ACUTE ACCENT", "LATIN SMALL LETTER L", "LATIN SMALL LETTER I", "LATIN SMALL LETTER E"]
+```
+
+---
+
+## `clusters`
+
+**Description:**
+Breaks the text into a list of unicode graphical clusters. Clusters are what
+you typically think of when you think of "letters" or "characters". If you're
+in a text editor and you hit the left or right arrow key, it will move the
+cursor by one graphical cluster.
+
+**Usage:**
+```markdown
+clusters(text: Text) -> [Text]
+```
+
+**Parameters:**
+
+- `text`: The text to be broken into graphical clusters.
+
+**Returns:**
+A list of graphical clusters (`[Text]`) within the text.
+
+**Example:**
+```markdown
+>> "Amélie":clusters()
+= ["A", "m", "é", "l", "i", "e"] : [Text]
+```
+
+---
+
+## `codepoints`
+
+**Description:**
+Returns a list of Unicode code points for the text.
+
+**Usage:**
+```markdown
+codepoints(text: Text) -> [Int32]
+```
+
+**Parameters:**
+
+- `text`: The text from which to extract Unicode code points.
+
+**Returns:**
+A list of Unicode code points (`[Int32]`).
+
+**Example:**
+```markdown
+>> "Amélie":codepoints()
+= [65_i32, 109_i32, 101_i32, 769_i32, 108_i32, 105_i32, 101_i32] : [Int32]
+```
+
+---
+
+## `from_c_string`
+
+**Description:**
+Converts a C-style string to a `Text` value.
+
+**Usage:**
+```markdown
+from_c_string(str: CString) -> Text
+```
+
+**Parameters:**
+
+- `str`: The C-style string to be converted.
+
+**Returns:**
+A `Text` value representing the C-style string.
+
+**Example:**
+```markdown
+from_c_string(CString("Hello")) // "Hello"
+```
+
+---
+
+## `has`
+
+**Description:**
+Checks if the `Text` contains a target substring.
+
+**Usage:**
+```markdown
+has(text: Text, target: Text, where: Where = Where.Anywhere) -> Bool
+```
+
+**Parameters:**
+
+- `text`: The text to be searched.
+- `target`: The substring to search for.
+- `where`: The location to search (`Where.Anywhere` by default).
+
+**Returns:**
+`yes` if the target substring is found, `no` otherwise.
+
+**Example:**
+```markdown
+has("Hello, world!", "world") // yes
+```
+
+---
+
+## `join`
+
+**Description:**
+Joins a list of text pieces with a specified glue.
+
+**Usage:**
+```markdown
+join(glue: Text, pieces: [Text]) -> Text
+```
+
+**Parameters:**
+
+- `glue`: The text used to join the pieces.
+- `pieces`: The list of text pieces to be joined.
+
+**Returns:**
+A single `Text` value with the pieces joined by the glue.
+
+**Example:**
+```markdown
+join(", ", ["apple", "banana", "cherry"]) // "apple, banana, cherry"
+```
+
+---
+
+## `lower`
+
+**Description:**
+Converts all characters in the text to lowercase.
+
+**Usage:**
+```markdown
+lower(text: Text) -> Text
+```
+
+**Parameters:**
+
+- `text`: The text to be converted to lowercase.
+
+**Returns:**
+The lowercase version of the text.
+
+**Example:**
+```markdown
+lower("HELLO") // "hello"
+```
+
+---
+
+## `num_bytes`
+
+**Description:**
+Returns the number of bytes used by the text.
+
+**Usage:**
+```markdown
+num_bytes(text: Text) -> Int
+```
+
+**Parameters:**
+
+- `text`: The text to measure.
+
+**Returns:**
+The number of bytes used by the text.
+
+**Example:**
+```markdown
+num_bytes("Hello") // 5
+```
+
+---
+
+## `num_clusters`
+
+**Description:**
+Returns the number of clusters in the text.
+
+**Usage:**
+```markdown
+num_clusters(text: Text) -> Int
+```
+
+**Parameters:**
+
+- `text`: The text to measure.
+
+**Returns:**
+The number of clusters in the text.
+
+**Example:**
+```markdown
+num_clusters("Hello") // 5
+```
+
+---
+
+## `num_codepoints`
+
+**Description:**
+Returns the number of Unicode code points in the text.
+
+**Usage:**
+```markdown
+num_codepoints(text: Text) -> Int
+```
+
+**Parameters:**
+
+- `text`: The text to measure.
+
+**Returns:**
+The number of Unicode code points in the text.
+
+**Example:**
+```markdown
+num_codepoints("Hello") // 5
+```
+
+---
+
+## `quoted`
+
+**Description:**
+Formats the text as a quoted string.
+
+**Usage:**
+```markdown
+quoted(text: Text, color: Bool = no) -> Text
+```
+
+**Parameters:**
+
+- `text`: The text to be quoted.
+- `color`: Whether to add color formatting (default is `no`).
+
+**Returns:**
+The text formatted as a quoted string.
+
+**Example:**
+```markdown
+quoted("Hello") // "\"Hello\""
+```
+
+---
+
+## `replace`
+
+**Description:**
+Replaces occurrences of a pattern in the text with a replacement string.
+
+**Usage:**
+```markdown
+replace(text: Text, pattern: Text, replacement: Text, limit: Int = -1) -> Text
+```
+
+**Parameters:**
+
+- `text`: The text in which to perform replacements.
+- `pattern`: The substring to be replaced.
+- `replacement`: The text to replace the pattern with.
+- `limit`: The maximum number of replacements (default is `-1`, meaning no limit).
+
+**Returns:**
+The text with occurrences of the pattern replaced.
+
+**Example:**
+```markdown
+replace("Hello world", "world", "there") // "Hello there"
+```
+
+---
+
+## `split`
+
+**Description:**
+Splits the text into a list of substrings based on a delimiter.
+
+**Usage:**
+```markdown
+split(text: Text, split: Text) -> [Text]
+```
+
+**Parameters:**
+
+- `text`: The text to be split.
+- `split`: The delimiter used to split the text.
+
+**Returns:**
+A list of substrings resulting from the split.
+
+**Example:**
+```markdown
+split("apple,banana,cherry", ",") // ["apple", "banana", "cherry"]
+```
+
+---
+
+## `title`
+
+**Description:**
+Converts the text to title case (capitalizing the first letter of each word).
+
+**Usage:**
+```markdown
+title(text: Text) -> Text
+```
+
+**Parameters:**
+
+- `text`: The text to be converted to title case.
+
+**Returns:**
+The text in title case.
+
+**Example:**
+```markdown
+title("hello world") // "Hello World"
+```
+
+---
+
+## `trimmed`
+
+**Description:**
+Trims characters from the beginning and end of the text.
+
+**Usage:**
+```markdown
+trimmed(text: Text, trim: Text = " {\n\r\t}", where: Where = Where.Anywhere) -> Text
+```
+
+**Parameters:**
+
+- `text`: The text to be trimmed.
+- `trim`: The set of characters to remove (default is `" {\n\r\t}"`).
+- `where`: Specifies where to trim (`Where.Anywhere` by default).
+
+**Returns:**
+The trimmed text.
+
+**Example:**
+```markdown
+trimmed(" Hello ") // "Hello"
+```
+
+---
+
+## `upper`
+
+**Description:**
+Converts all characters in the text to uppercase.
+
+**Usage:**
+```markdown
+upper(text: Text) -> Text
+```
+
+**Parameters:**
+
+- `text`: The text to be converted to uppercase.
+
+**Returns:**
+The uppercase version of the text.
+
+**Example:**
+```markdown
+upper("hello") // "HELLO"
+```
+
+---
+
+## `without`
+
+**Description:**
+Removes all occurrences of a target substring from the text.
+
+**Usage:**
+```markdown
+without(text: Text, target: Text, where: Where = Where.Anywhere) -> Text
+```
+
+**Parameters:**
+
+- `text`: The text from which to remove substrings.
+- `target`: The substring to remove.
+- `where`: The location to remove the target (`Where.Anywhere` by default).
+
+**Returns:**
+The text with occurrences of the target removed.
+
+**Example:**
+```markdown
+without("Hello world", "world") // "Hello "
+```
+
+---