diff options
Diffstat (limited to 'api')
| -rw-r--r-- | api/booleans.md | 60 | ||||
| -rw-r--r-- | api/integers.md | 338 | ||||
| -rw-r--r-- | api/nums.md | 1346 | ||||
| -rw-r--r-- | api/text.md | 753 |
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 " +``` + +--- |
