// reference

Scalar Types

Built-in scalar classes: String, Integer, Integer16, Integer32, Byte, Real, Boolean, Char. Integer64 is another spelling of Integer.

All scalar classes are modeled as inheriting Any and implementing Comparable.

String

A double-quoted string interprets backslash escapes: \n (newline), \t (tab), \r (carriage return), \0 (null), \\ (backslash), \" (double quote), and \u{H...} (a Unicode code point in hex); any other escape is an error. A single-quoted string is raw — every character, backslash included, is literal — which is convenient for regular-expression patterns and paths: '\d+', 'C:\dir'.

Method Arguments Returns Description
length none Integer Number of characters.
index_of ch: String Integer First index of ch, or -1.
substring start: Integer, end: Integer String Slice from start (inclusive) to end (exclusive).
to_upper none String Uppercase copy.
to_lower none String Lowercase copy.
to_integer none Integer Parse integer value.
to_real none Real Parse floating-point value.
contains substr: String Boolean True if substring exists.
starts_with prefix: String Boolean True if string starts with prefix.
ends_with suffix: String Boolean True if string ends with suffix.
trim none String Remove leading/trailing whitespace.
replace old: String, new: String String Replace all occurrences of old.
pad_end pad: String, length: Integer String Pad the right side with pad until the string reaches length. Returns unchanged if already at or above length.
pad_start pad: String, length: Integer String Pad the left side with pad until the string reaches length. Returns unchanged if already at or above length.
replicate n: Integer String Return the string repeated n times.
char_at idx: Integer Char Character at index.
chars none Array[Char] New array of characters in string order.
to_bytes none Array[Byte] UTF-8 bytes of the string.
split delim: String Array[String] Split into an array.
join parts: Array[String] String Concatenate parts with this string as the separator.
plus other: Any String Concatenate with other.
equals other: Any Boolean Equality check.
not_equals other: Any Boolean Inequality check.
less_than other: String Boolean Lexicographic <.
less_than_or_equal other: String Boolean Lexicographic <=.
greater_than other: String Boolean Lexicographic >.
greater_than_or_equal other: String Boolean Lexicographic >=.
compare other: Any Integer Ordering as integer result.
hash none Integer Hash code.
cursor none StringCursor Create character iterator.

Laws:

  • s.chars().length = s.length
  • s.chars().get(i) = s.char_at(i) for every valid i

Examples:

let xs: Array[Char] := "cat".chars()
print(xs)        -- [#c, #a, #t]
print(xs.length) -- 3
print(xs.get(1)) -- #a

to_bytes() uses UTF-8 encoding and returns an Array[Byte] with byte values in 0..255.

let bytes: Array[Byte] := "cat".to_bytes()
print(bytes) -- [99, 97, 116]

create String.from_bytes(bytes) is the inverse: it decodes an Array[Byte] as UTF-8 and returns the String. It raises if the bytes are not valid UTF-8, rather than substituting replacement characters, so create String.from_bytes(s.to_bytes()) always gives back s exactly.

let bytes: Array[Byte] := "héllo".to_bytes()
let text: String := create String.from_bytes(bytes)
print(text) -- "héllo"

Integer

Integer is a signed 64-bit integer (range -2^63 .. 2^63-1) on every backend. Arithmetic is checked: +, -, *, unary -, and ^ raise on overflow, and / and % raise on a zero divisor.

Integer64 is an alias: it names exactly the same type, so the two are interchangeable everywhere (let n: Integer64 := 5 and let m: Integer := n both typecheck). The fixed-width siblings are Integer16, Integer32 and Byte, below.

Bitwise operations use 32-bit integer semantics. Bit index 0 is the least-significant bit. For method calls on integer literals, wrap the literal in parentheses: (5).bitwise_left_shift(1).

Method Arguments Returns Description
to_string none / base: Integer String Convert to string. If provided, base must be one of 2, 8, 10 or 16
abs none Integer Absolute value.
min other: Integer Integer Smaller of two values.
max other: Integer Integer Larger of two values.
pick none Integer Random integer in [0, self).
bitwise_left_shift n: Integer Integer Left-shift by n bit positions.
bitwise_right_shift n: Integer Integer Arithmetic right-shift by n bit positions.
bitwise_logical_right_shift n: Integer Integer Logical right-shift by n bit positions.
bitwise_rotate_left n: Integer Integer Rotate bits left by n positions.
bitwise_rotate_right n: Integer Integer Rotate bits right by n positions.
bitwise_is_set n: Integer Boolean True if bit n is set.
bitwise_set n: Integer Integer Return value with bit n set to 1.
bitwise_unset n: Integer Integer Return value with bit n cleared to 0.
bitwise_and other: Integer Integer Bitwise AND.
bitwise_or other: Integer Integer Bitwise OR.
bitwise_xor other: Integer Integer Bitwise XOR.
bitwise_not none Integer Bitwise complement.
plus other: Integer Integer Addition.
minus other: Integer Integer Subtraction.
times other: Integer Integer Multiplication.
divided_by other: Integer Real Division.
equals other: Any Boolean Equality check.
not_equals other: Any Boolean Inequality check.
less_than other: Integer Boolean Numeric <.
less_than_or_equal other: Integer Boolean Numeric <=.
greater_than other: Integer Boolean Numeric >.
greater_than_or_equal other: Integer Boolean Numeric >=.
compare other: Any Integer Ordering as integer result.
hash none Integer Hash code.
to_char none Char Return the character whose Unicode code point equals this integer. Valid for BMP code points (0–65535).
to_byte none Byte Convert to a Byte; raises unless the value is in 0..255.
to_integer16 none Integer16 Convert to an Integer16; raises unless the value is in -32768..32767.
to_integer32 none Integer32 Convert to an Integer32; raises unless the value is in -2147483648..2147483647.

Byte

Byte is an unsigned 8-bit integer (range 0..255). It is the element type of String.to_bytes() and of binary file I/O (Array[Byte]).

Byte is a distinct type, related to Integer the way Integer is related to Real: there is no implicit conversion in either direction.

  • Byte literals: an integer literal with a u8 suffix is a Byte: 12u8, 0xFFu8, 0b1010u8, 0o17u8, 1_0u8. The value must be in 0..255, and is checked when the program is parsed. (The suffix is u8, not b, because b is a hex digit.) An unsuffixed literal is always an Integer, so let b: Byte := 65 is a type error; write 65u8. There are no negative byte literals: -5u8 is the Integer -5.
  • Making a Byte from a value: n.to_byte() on an Integer (raises unless 0 <= n <= 255), or reading one out of an Array[Byte].
  • Getting an Integer: b.to_integer(). Assigning a Byte to an Integer variable or passing it to an Integer parameter is a type error.
  • Arithmetic (+ - * / % ^, unary -) promotes to Integer, so the result of b + b is an Integer and cannot overflow a Byte; narrow it back with (b + b).to_byte(). Mixing with Real promotes to Real.
  • Comparison (= /= < <= > >=) is between two Bytes. Comparing a Byte with an Integer needs b.to_integer() first, just as comparing an Integer with a Real needs a conversion. b.equals(x) is true only when x is a Byte of the same value.
  • convert does not change representation, so convert n to b: Byte on an Integer is rejected; use to_byte(). A Byte held in an Any keeps its type: type_of reports "Byte" and convert a to b: Byte succeeds.
  • Bitwise methods work on 8 bits and return a Byte, unlike Integer's 32-bit bitwise operations: (195).to_byte().bitwise_not() is 60. Bit indexes for bitwise_is_set, bitwise_set and bitwise_unset must be in 0..7; shift counts must be non-negative, and shifting by 8 or more clears every bit.
  • Java interop: a Byte passed to a Java int or long parameter is passed as an integer. Passed to a Java byte parameter, it is the same 8 bits read as signed, so 200 arrives as -56.
Method Arguments Returns Description
to_string none String Base-10 text.
to_string base: Integer String Text in base (2, 8, 10, or 16; any other value raises).
to_integer none Integer The value, 0..255.
to_char none Char The character with this code point.
to_hex none String Two lowercase hex digits, e.g. "0a".
to_integer16 none Integer16 Widen to an Integer16.
to_integer32 none Integer32 Widen to an Integer32.
min other: Byte Byte Smaller of two values.
max other: Byte Byte Larger of two values.
bitwise_left_shift n: Integer Byte Left-shift, dropping bits shifted out of the top.
bitwise_right_shift n: Integer Byte Right-shift.
bitwise_logical_right_shift n: Integer Byte Same as bitwise_right_shift; a Byte is never negative.
bitwise_rotate_left n: Integer Byte Rotate bits left within 8 bits.
bitwise_rotate_right n: Integer Byte Rotate bits right within 8 bits.
bitwise_is_set n: Integer Boolean True if bit n (0..7) is set.
bitwise_set n: Integer Byte Value with bit n set to 1.
bitwise_unset n: Integer Byte Value with bit n cleared to 0.
bitwise_and x: Byte Byte Bitwise AND.
bitwise_or x: Byte Byte Bitwise OR.
bitwise_xor x: Byte Byte Bitwise XOR.
bitwise_not none Byte Complement within 8 bits (255 - self).
equals other: Any Boolean True only for a Byte of the same value.
not_equals other: Any Boolean Inequality check.
compare other: Any Integer Ordering as integer result.
hash none Integer Hash code.
let bytes: Array[Byte] := "é".to_bytes()
let magic: Array[Byte] := [0x89u8, 0x50u8, 0x4Eu8, 0x47u8]
print(bytes)                       -- [195, 169]
let b: Byte := bytes.get(0)
print(b.to_hex())                  -- "c3"
print(b.bitwise_not())             -- 60
let total: Integer := b + bytes.get(1)
print(total)                       -- 364
let narrowed: Byte := (total - 200).to_byte()
print(narrowed)                    -- 164

Integer16 and Integer32

Integer16 and Integer32 are signed fixed-width integers: -32768..32767 and -2147483648..2147483647. They are for binary formats, protocols and interop where a value has an exact width. Like Byte, each is a distinct type related to Integer the way Integer is related to Real.

  • No implicit conversion. None of Integer, Integer16, Integer32 and Byte converts to another without a call, in either direction. let b: Integer32 := a where a is an Integer16 is a type error; write a.to_integer32().
  • Literals. An integer literal with an i16 or i32 suffix: 300i16, 0xFFFFi32, 1_000i32. A negative one is written with a leading - and is a single literal of that type: -5i16 is an Integer16, and -32768i16 is valid. (Elsewhere -x on a sized variable promotes to Integer, like any arithmetic.) An unsuffixed literal is an Integer, so let a: Integer16 := 5 is a type error; write 5i16. A literal outside the type's range is rejected.
  • Conversions. Narrowing is checked: n.to_integer16(), n.to_integer32() and n.to_byte() raise unless the value fits. Widening (Byte to Integer16/Integer32, Integer16 to Integer32) also uses these methods and always succeeds. x.to_integer() gives the Integer.
  • Arithmetic (+ - * / % ^, unary - on a variable) promotes to Integer, so the result of a + a is an Integer and cannot overflow the narrow type; narrow it back with (a + a).to_integer16(). Mixing with Real promotes to Real.
  • Comparison (= /= < <= > >=) is between two values of the same type. Comparing across types needs a conversion first. a.equals(x) is true only when x has the same type and value.
  • convert does not change representation, so convert n to a: Integer16 on an Integer is rejected. A value keeps its type inside an Any: type_of reports "Integer16", and convert x to a: Integer16 succeeds only for one.
  • Bitwise methods work on, and wrap to, the type's own width, and return the same type: 0i16.bitwise_not() is -1i16, and 32767i16.bitwise_left_shift(1) is -2i16. Right shift copies the sign bit; bitwise_logical_right_shift shifts in zeros. Bit indexes must be 0..15 (Integer16) or 0..31 (Integer32); shift counts must be non-negative, and shifting by the width or more clears every bit (except an arithmetic right shift of a negative value, which gives -1). abs raises for the minimum value, which has no positive counterpart. (Integer's own bitwise methods keep their 32-bit behaviour.)
  • Java interop: passed to a reflective Java call, an Integer16 or Integer32 goes as an integer, so it can be used wherever an Integer can.

Both types have the same methods. T below is the type itself.

Method Arguments Returns Description
to_string none String Base-10 text.
to_string base: Integer String Text in base (2, 8, 10, or 16; any other value raises). A negative value is rendered with a leading - and its magnitude.
to_integer none Integer The value as an Integer.
to_byte none Byte Raises unless the value is in 0..255.
to_integer16 none Integer16 Raises unless the value fits.
to_integer32 none Integer32 Raises unless the value fits.
abs none T Absolute value; raises for the minimum value.
min other: T T Smaller of two values.
max other: T T Larger of two values.
bitwise_left_shift n: Integer T Left-shift, dropping bits shifted out.
bitwise_right_shift n: Integer T Arithmetic right-shift (the sign bit is copied).
bitwise_logical_right_shift n: Integer T Right-shift, shifting in zeros.
bitwise_rotate_left n: Integer T Rotate bits left within the width.
bitwise_rotate_right n: Integer T Rotate bits right within the width.
bitwise_is_set n: Integer Boolean True if bit n is set.
bitwise_set n: Integer T Value with bit n set to 1.
bitwise_unset n: Integer T Value with bit n cleared to 0.
bitwise_and x: T T Bitwise AND.
bitwise_or x: T T Bitwise OR.
bitwise_xor x: T T Bitwise XOR.
bitwise_not none T Bitwise complement.
equals other: Any Boolean True only for the same type and value.
not_equals other: Any Boolean Inequality check.
compare other: Any Integer Ordering as integer result.
hash none Integer Hash code.
let port: Integer16 := 8080i16
let offset: Integer32 := -70000i32
print(port.to_string(16))            -- "1f90"
print(offset.abs())                  -- 70000
print(port.bitwise_left_shift(4))    -- -1792 (129280 wrapped to 16 bits)
let wide: Integer := port + offset   -- arithmetic promotes to Integer
print(wide)                          -- -61920
let back: Integer16 := (wide + 61920 + 100).to_integer16()
print(back)                          -- 100

Real

Real literals must include at least one digit after the decimal point. Valid forms include 3.14, 10.0, .5, and 12.0e-3. Forms such as 10. and 12.e-3 are not valid real literals.

Real is an IEEE-754 double on every backend, in representation and arithmetic. Division by zero follows IEEE rather than raising: 1.0 / 0.0 is Infinity, -1.0 / 0.0 is -Infinity, and 0.0 / 0.0 is NaN. (Integer division by zero, by contrast, raises.)

Method Arguments Returns Description
to_string none String Convert to string.
abs none Real Absolute value.
min other: Real Real Smaller of two values.
max other: Real Real Larger of two values.
round none Integer Round to the nearest integer, halves up (2.5 to 3, -2.5 to -2). Raises as floor does.
floor none Integer Largest integer not above the value. Raises for NaN, an infinity, or a value outside the Integer range.
ceiling none Integer Smallest integer not below the value. Raises as floor does.
truncate none Integer The value with its fraction dropped (toward zero). Raises as floor does.
to_fixed places: Integer Real Round to places decimal places using half-up rounding.
sqrt none Real Square root.
cbrt none Real Cube root.
exp none Real e raised to the value.
log none Real Natural logarithm.
log10 none Real Base-10 logarithm.
log2 none Real Base-2 logarithm, exact for powers of two.
power exponent: Real Real The value raised to exponent; the method form of ^.
sin, cos, tan none Real Trigonometric functions of an angle in radians.
asin, acos, atan none Real Inverse trigonometric functions, in radians.
atan2 x: Real Real y.atan2(x) is the angle of the point (x, y), in radians, -PI..PI.
to_radians none Real Degrees to radians.
to_degrees none Real Radians to degrees.
sign none Real -1.0, 0.0 or 1.0 by the value's sign (-0.0 and NaN are returned unchanged).
clamp low: Real, high: Real Real The value limited to low..high. Raises unless low <= high.
hypot other: Real Real sqrt(value^2 + other^2), without overflowing in between.
is_nan none Boolean True if the value is NaN.
is_infinite none Boolean True if the value is ±Infinity.
is_finite none Boolean True if the value is neither NaN nor infinite.
plus other: Real Real Addition.
minus other: Real Real Subtraction.
times other: Real Real Multiplication.
divided_by other: Real Real Division.
equals other: Any Boolean Equality check.
not_equals other: Any Boolean Inequality check.
less_than other: Real Boolean Numeric <.
less_than_or_equal other: Real Boolean Numeric <=.
greater_than other: Real Boolean Numeric >.
greater_than_or_equal other: Real Boolean Numeric >=.
compare other: Any Integer Ordering as integer result.
hash none Integer Hash code.

The math methods follow IEEE-754 as division does: outside a function's domain the result is NaN or an infinity, not an error. (-1.0).sqrt and 2.0.asin are NaN, 0.0.log is -Infinity. Test with is_nan/is_finite. Only the Integer-returning round, floor, ceiling and truncate raise, since no Integer stands for NaN, an infinity, or a value outside the Integer range.

Constants

Constant Value
Real.PI π, 3.141592653589793
Real.E e, 2.718281828459045
let area: Real := Real.PI * (r ^ 2)
let angle: Real := 45.0.to_radians
print(angle.sin)                  -- 0.7071067811865475

Boolean

Method Arguments Returns Description
to_string none String Convert to string.
and other: Boolean Boolean Logical conjunction.
or other: Boolean Boolean Logical disjunction.
not none Boolean Logical negation.
equals other: Any Boolean Equality check.
not_equals other: Any Boolean Inequality check.
compare other: Any Integer Ordering as integer result.
hash none Integer Hash code.

Char

Method Arguments Returns Description
to_string none String Convert to one-character string.
to_upper none String Uppercase character as a string.
to_lower none String Lowercase character as a string.
to_integer none Integer Unicode code point of the character. Valid for BMP code points (0–65535).
compare other: Any Integer Ordering as integer result.
hash none Integer Hash code.

Examples

let s := "  Nex  "
print(s.trim().to_upper())        -- "NEX"
print(s.contains("ex"))           -- true

let n: Integer := 7
print(n.plus(5))                  -- 12
print(n.pick())                   -- random integer in [0, 7)
print(5.bitwise_left_shift(1))    -- 10
print(6.bitwise_and(3))           -- 2

let r: Real := 3.6
print(r.round())                  -- 4

let b: Boolean := true
print(b.and(false))               -- false