Strings and characters
String is immutable Unicode text. Char is one Unicode code point. They are
distinct types: a one-character string is not a Char, and a Char is not an
Int even though the JavaScript backend stores its code-point value as a
number.
Construct and concatenate text
Section titled “Construct and concatenate text”Quoted strings use "...", characters use single quotes, and ++
concatenates strings:
func greeting(name : String) -> String do "Hello, " ++ name ++ "!"endUse String.join(values, separator) to combine an array of strings without a
manual concatenation loop:
func main() -> Unit do Console.println(String.join(["a", "b", "c"], ", "));endExplicit conversions
Section titled “Explicit conversions”Associated conversion methods include:
Int.to_string();Int.to_double();Int64.to_int(),Int64.to_double(), andInt64.to_string();Bool.to_int()andBool.to_string();Char.to_int()andChar.to_string();Double.to_string().
The reverse direction parses decimal text with an optional sign, answering
with an Option that is empty for any other shape: Int.parse(),
Int64.parse() (which is also empty outside the 64-bit range), and
Double.parse() (which accepts one fraction and one exponent).
Conversions are explicit; context never silently changes one primitive type into another.
Char.from_codepoint(value) constructs a character from an integer code
point:
func main() -> Unit do character = Char.from_codepoint(0x1f600); Console.println(character.to_string()); Debug.trace(character.to_int());endTrim known prefixes and suffixes
Section titled “Trim known prefixes and suffixes”trim_prefix(prefix) and trim_suffix(suffix) remove one known edge
string. When the string does not start or end with the given text, they
return the string unchanged:
func module_basename(filename : String) -> String do filename.trim_suffix(".nl")endBoth operations trim at most one occurrence at the boundary and never scan
for repeated matches. Pair them with starts_with / ends_with when the
caller needs to know whether a trim happened.
Cursor-based string access
Section titled “Cursor-based string access”Strings do not expose integer indexing or a code-point length() method.
Instead, a StringCursor represents a boundary in one specific string:
func first_character(value : String) -> Option[Char] do value.character_at(value.start_cursor())endThe cursor API includes:
start_cursor()andend_cursor();next_cursor(cursor)andprevious_cursor(cursor), returningOptionat the boundaries;character_at(cursor)andunsafe_character_at(cursor);slice(from, to)for a half-open cursor range;utf16_distance(from, to)for protocols that need UTF-16 offsets.
A cursor belongs to the string from which it was obtained. Passing it to a different string is outside the API contract.
Iterate by code point
Section titled “Iterate by code point”The standard library supplies an iterable provider for String, so
foreach visits characters rather than backend UTF-16 code units:
func print_characters(value : String) -> Unit do foreach character in value do Console.println(character.to_string()); end;endThis keeps supplementary Unicode characters such as '😀' as one Char.
Floating-point helpers
Section titled “Floating-point helpers”The Double view provides sqrt(), pow(exponent), floor_to_int(), and
truncate_to_int(). The last two are explicit lossy conversions with
different rounding rules; neither is an implicit numeric conversion.
Next: Sorted maps.