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 and Hashable.
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.lengths.chars().get(i) = s.char_at(i)for every validi
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
u8suffix is aByte:12u8,0xFFu8,0b1010u8,0o17u8,1_0u8. The value must be in0..255, and is checked when the program is parsed. (The suffix isu8, notb, becausebis a hex digit.) An unsuffixed literal is always anInteger, solet b: Byte := 65is a type error; write65u8. There are no negative byte literals:-5u8is theInteger-5. - Making a
Bytefrom a value:n.to_byte()on anInteger(raises unless0 <= n <= 255), or reading one out of anArray[Byte]. - Getting an
Integer:b.to_integer(). Assigning aByteto anIntegervariable or passing it to anIntegerparameter is a type error. - Arithmetic (
+ - * / % ^, unary-) promotes toInteger, so the result ofb + bis anIntegerand cannot overflow aByte; narrow it back with(b + b).to_byte(). Mixing withRealpromotes toReal. - Comparison (
= /= < <= > >=) is between twoBytes. Comparing aBytewith anIntegerneedsb.to_integer()first, just as comparing anIntegerwith aRealneeds a conversion.b.equals(x)is true only whenxis aByteof the same value. convertdoes not change representation, soconvert n to b: Byteon anIntegeris rejected; useto_byte(). AByteheld in anAnykeeps its type:type_ofreports"Byte"andconvert a to b: Bytesucceeds.- Bitwise methods work on 8 bits and return a
Byte, unlikeInteger's 32-bit bitwise operations:(195).to_byte().bitwise_not()is60. Bit indexes forbitwise_is_set,bitwise_setandbitwise_unsetmust be in0..7; shift counts must be non-negative, and shifting by 8 or more clears every bit. - Java interop: a
Bytepassed to a Javaintorlongparameter is passed as an integer. Passed to a Javabyteparameter, it is the same 8 bits read as signed, so200arrives 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,Integer32andByteconverts to another without a call, in either direction.let b: Integer32 := awhereais anInteger16is a type error; writea.to_integer32(). - Literals. An integer literal with an
i16ori32suffix:300i16,0xFFFFi32,1_000i32. A negative one is written with a leading-and is a single literal of that type:-5i16is anInteger16, and-32768i16is valid. (Elsewhere-xon a sized variable promotes toInteger, like any arithmetic.) An unsuffixed literal is anInteger, solet a: Integer16 := 5is a type error; write5i16. A literal outside the type's range is rejected. - Conversions. Narrowing is checked:
n.to_integer16(),n.to_integer32()andn.to_byte()raise unless the value fits. Widening (BytetoInteger16/Integer32,Integer16toInteger32) also uses these methods and always succeeds.x.to_integer()gives theInteger. - Arithmetic (
+ - * / % ^, unary-on a variable) promotes toInteger, so the result ofa + ais anIntegerand cannot overflow the narrow type; narrow it back with(a + a).to_integer16(). Mixing withRealpromotes toReal. - Comparison (
= /= < <= > >=) is between two values of the same type. Comparing across types needs a conversion first.a.equals(x)is true only whenxhas the same type and value. convertdoes not change representation, soconvert n to a: Integer16on anIntegeris rejected. A value keeps its type inside anAny:type_ofreports"Integer16", andconvert x to a: Integer16succeeds 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, and32767i16.bitwise_left_shift(1)is-2i16. Right shift copies the sign bit;bitwise_logical_right_shiftshifts in zeros. Bit indexes must be0..15(Integer16) or0..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).absraises 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
Integer16orInteger32goes as an integer, so it can be used wherever anIntegercan.
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 nearest integer. |
to_fixed |
places: Integer |
Real |
Round to places decimal places using half-up rounding. |
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. |
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