String #
Quest strings are immutable sequences of Unicode characters (UTF-8 encoded).
String Literal #
"This is a string literal"
String Interpolation #
Quest supports three styles of string formatting, inspired by Python and Rust:
1. F-Strings (Python-style) #
Use f"..." prefix for automatic variable interpolation from the current scope:
let name = "Alice"
let age = 30
puts(f"Hello {name}, you are {age} years old")
# Output: Hello Alice, you are 30 years old
F-strings are the simplest form - just prefix your string with f and reference variables directly. Plain strings ("..." without the f prefix) do NOT interpolate - "Hello {name}" is a literal string containing braces.
2. Explicit Formatting with .fmt() #
For more control, use the .fmt() method with positional or named arguments.
Positional Arguments #
"Welcome to {} in room {}".fmt("Biology", 202)
# Output: Welcome to Biology in room 202
"Item {0} costs ${1:.2}".fmt("Apple", 3.5)
# Output: Item Apple costs $3.50
Named Arguments #
Note: Named arguments are not yet implemented in Quest. Use positional arguments or f-strings instead.
Format Specifiers (Rust-style) #
Format specifiers control how values are displayed.
Number Formatting #
# Decimal precision
"{:.2}".fmt(3.14159) # 3.14
"{:.0}".fmt(3.14159) # 3
# Hexadecimal
"{:x}".fmt(255) # ff
"{:X}".fmt(255) # FF
"{:#x}".fmt(255) # 0xff
# Binary
"{:b}".fmt(10) # 1010
"{:#b}".fmt(10) # 0b1010
# Octal
"{:o}".fmt(8) # 10
"{:#o}".fmt(8) # 0o10
# Scientific notation
"{:e}".fmt(1000.0) # 1e3
"{:E}".fmt(1000.0) # 1E3
Width and Alignment #
# Width (minimum characters)
"{:5}".fmt("x") # " x" (right-aligned by default)
"{:5}".fmt(42) # " 42"
# Left align
"{:<5}".fmt("x") # "x "
# Right align (explicit)
"{:>5}".fmt("x") # " x"
# Center align
"{:^5}".fmt("x") # " x "
Fill Characters #
# Zero-padding for numbers
"{:05}".fmt(42) # "00042"
"{:0>5}".fmt(42) # "00042"
# Custom fill character
"{:->5}".fmt("x") # "----x"
"{:-<5}".fmt("x") # "x----"
"{:-^5}".fmt("x") # "--x--"
Sign Control #
# Always show sign
"{:+}".fmt(42) # "+42"
"{:+}".fmt(-42) # "-42"
# Space for positive numbers
"{: }".fmt(42) # " 42"
"{: }".fmt(-42) # "-42"
Combined Specifiers #
# Width + precision
"{:8.2}".fmt(3.14159) # " 3.14"
# Fill + align + width + precision
"{:0>8.2}".fmt(3.14) # "00003.14"
# Sign + width + precision
"{:+8.2}".fmt(3.14) # " +3.14"
Escaped Braces #
To include literal braces in the output, double them:
"Use {{}} for braces".fmt() # "Use {} for braces"
"{{name}}".fmt() # "{name}"
"Set: {{1, 2, 3}}".fmt() # "Set: {1, 2, 3}"
Format Specifier Syntax #
The full format syntax is:
{[argument]:[fill][align][sign][#][0][width][.precision][type]}
Where:
argument: Position (0, 1, ...) or name (optional)fill: Any character (default is space)align:<(left),>(right),^(center)sign:+(always),-(negative only, default),(space for positive)#: Alternate form (0x, 0b, 0o prefixes)0: Zero-padding (shorthand for:0>)width: Minimum width in charactersprecision: Number of decimal places for floatstype:x(hex),X(HEX),b(binary),o(octal),e(scientific),E(SCIENTIFIC)
String concatenation #
# Evaluates as: str_literal .. obj.str() .. string_literal .. expr
# expression here evaluates to a num and num.str() is accessed to provide
# the string.
"String" .. obj .. "adf" .. (3 + 4)
Multi-Line Strings #
"""
This is a multi-line string
Newline and indention levels are retained
But whitespace after the opening quotes
and whitespace after the last line are ignored.
"""
Documentation Blocks #
Quest has python style documentation blocks that use multi-line string syntax
type Cat {
"""
Soft kitty
Warm kitty
Little ball of fur
"""
}
puts(Cat._doc())
# Output:
# Soft kitty
# Warm kitty
# Little ball of fur
String Methods #
capitalize() #
Returns a new string with the first character converted to upper case and the rest lower case.
Returns: Str
Example:
let text = "hello world"
puts(text.capitalize()) # Hello world
let caps = "HELLO WORLD"
puts(caps.capitalize()) # Hello world
count(substring) #
Returns the number of times a substring occurs in the string.
Parameters:
substring- Substring to count
Returns: Num
Example:
let text = "hello world"
puts(text.count("l")) # 3
puts(text.count("o")) # 2
puts(text.count("ll")) # 1
puts(text.count("x")) # 0
encode(encoding) #
Returns an encoded version of the string.
Parameters:
encoding- Encoding type (e.g., "utf-8", "ascii")
Returns: Str
Example:
let text = "hello"
let encoded = text.encode("utf-8")
puts(encoded)
endswith(suffix) #
Returns true if the string ends with the specified suffix.
Parameters:
suffix- String to check at end
Returns: Bool
Example:
let filename = "document.txt"
puts(filename.endswith(".txt")) # true
puts(filename.endswith(".pdf")) # false
let path = "/home/user/"
puts(path.endswith("/")) # true
expandtabs(tabsize) #
Replaces tab characters with spaces using the specified tab size.
Parameters:
tabsize- Number of spaces per tab
Returns: Str
Example:
let text = "hello\tworld"
puts(text.expandtabs(4)) # hello world
puts(text.expandtabs(8)) # hello world
isalnum() #
Returns true if all characters in the string are alphanumeric (letters or numbers).
Returns: Bool
Example:
puts("abc123".isalnum()) # true
puts("hello".isalnum()) # true
puts("123".isalnum()) # true
puts("hello world".isalnum()) # false (has space)
puts("hello!".isalnum()) # false (has punctuation)
isalpha() #
Returns true if all characters in the string are alphabetic letters.
Returns: Bool
Example:
puts("hello".isalpha()) # true
puts("HelloWorld".isalpha()) # true
puts("hello123".isalpha()) # false (has numbers)
puts("hello world".isalpha()) # false (has space)
isascii() #
Returns true if all characters in the string are ASCII characters.
Returns: Bool
Example:
puts("hello".isascii()) # true
puts("hello123".isascii()) # true
puts("hello!@#".isascii()) # true
isdecimal() #
Returns true if all characters in the string are decimal digits.
Returns: Bool
Example:
puts("12345".isdecimal()) # true
puts("123.45".isdecimal()) # false (has decimal point)
puts("123a".isdecimal()) # false (has letter)
isdigit() #
Returns true if all characters in the string are digits.
Returns: Bool
Example:
puts("12345".isdigit()) # true
puts("0".isdigit()) # true
puts("123a".isdigit()) # false
puts("12.34".isdigit()) # false
islower() #
Returns true if all alphabetic characters in the string are lower case.
Returns: Bool
Example:
puts("hello".islower()) # true
puts("hello123".islower()) # true
puts("Hello".islower()) # false
puts("HELLO".islower()) # false
isnumeric() #
Returns true if all characters in the string are numeric.
Returns: Bool
Example:
puts("12345".isnumeric()) # true
puts("123".isnumeric()) # true
puts("12.34".isnumeric()) # false
puts("12a".isnumeric()) # false
isspace() #
Returns true if all characters in the string are whitespace.
Returns: Bool
Example:
puts(" ".isspace()) # true
puts("\t\n".isspace()) # true
puts(" a ".isspace()) # false
puts("".isspace()) # false
istitle() #
Returns true if the string follows title case rules (first letter of each word capitalized).
Returns: Bool
Example:
puts("Hello World".istitle()) # true
puts("Hello world".istitle()) # false
puts("HELLO WORLD".istitle()) # false
puts("hello world".istitle()) # false
isupper() #
Returns true if all alphabetic characters in the string are upper case.
Returns: Bool
Example:
puts("HELLO".isupper()) # true
puts("HELLO123".isupper()) # true
puts("Hello".isupper()) # false
puts("hello".isupper()) # false
lower() #
Converts all characters in the string to lower case.
Returns: Str
Example:
let text = "HELLO WORLD"
puts(text.lower()) # hello world
let mixed = "HeLLo WoRLd"
puts(mixed.lower()) # hello world
ltrim() #
Removes whitespace from the left (beginning) of the string.
Returns: Str
Example:
let text = " hello world"
puts(text.ltrim()) # hello world
let tabs = "\t\thello"
puts(tabs.ltrim()) # hello
rtrim() #
Removes whitespace from the right (end) of the string.
Returns: Str
Example:
let text = "hello world "
puts(text.rtrim()) # hello world
let newlines = "hello\n\n"
puts(newlines.rtrim()) # hello
trim() #
Removes whitespace from both ends of the string.
Returns: Str
Example:
let text = " hello world "
puts(text.trim()) # hello world
let mixed = "\t\nhello\n\t"
puts(mixed.trim()) # hello
title() #
Converts the first character of each word to upper case.
Returns: Str
Example:
let text = "hello world"
puts(text.title()) # Hello World
let lower = "the quick brown fox"
puts(lower.title()) # The Quick Brown Fox
upper() #
Converts all characters in the string to upper case.
Returns: Str
Example:
let text = "hello world"
puts(text.upper()) # HELLO WORLD
let mixed = "HeLLo WoRLd"
puts(mixed.upper()) # HELLO WORLD
split(delimiter) #
Splits the string by delimiter and returns an array of substrings.
Parameters:
delimiter- String to split on (empty string splits into characters)
Returns: Array
Example:
let text = "hello,world,quest"
let parts = text.split(",")
puts(parts) # [hello, world, quest]
let sentence = "hello world"
let words = sentence.split(" ")
puts(words) # [hello, world]
# Split into characters
let chars = "hello".split("")
puts(chars) # [h, e, l, l, o]
slice(start, end) #
Extracts a substring from start index to end index (exclusive). Supports negative indices.
Parameters:
start- Starting index (negative counts from end)end- Ending index, exclusive (negative counts from end)
Returns: Str
Example:
let text = "hello world"
puts(text.slice(0, 5)) # hello
puts(text.slice(6, 11)) # world
puts(text.slice(0, -6)) # hello
puts(text.slice(-5, 11)) # world
replace(old, new) #
Replaces all occurrences of a substring with another string.
Parameters:
old- Substring to find and replacenew- Replacement string
Returns: Str
Example:
let text = "Hello World"
puts(text.replace("World", "Quest")) # Hello Quest
let repeated = "test test test"
puts(repeated.replace("test", "pass")) # pass pass pass
let code = "foo_bar_baz"
puts(code.replace("_", "-")) # foo-bar-baz
# When substring doesn't exist, returns original string
let unchanged = "hello"
puts(unchanged.replace("xyz", "abc")) # hello
Type Conversion Methods #
to_int() #
Converts a string to an integer. Supports decimal, hexadecimal (0x), binary (0b), and octal (0o) formats. Underscores are allowed as digit separators and whitespace is trimmed automatically.
Parameters: None
Returns: Int
Raises: Error if the string cannot be parsed as an integer
Example:
# Decimal
puts("123".to_int()) # 123
puts("-456".to_int()) # -456
puts("1_000_000".to_int()) # 1000000
# Hexadecimal
puts("0xFF".to_int()) # 255
puts("0xDEADBEEF".to_int()) # 3735928559
# Binary
puts("0b1010".to_int()) # 10
puts("0b11111111".to_int()) # 255
# Octal
puts("0o755".to_int()) # 493
# With whitespace
puts(" 123 ".to_int()) # 123
# Error cases
try
"abc".to_int() # Error: Invalid integer
catch e
puts(e.message())
end
try
"123.45".to_int() # Error: Invalid integer (floats not accepted)
catch e
puts(e.message())
end
to_float() #
Converts a string to a floating-point number. Supports decimal notation, scientific notation, and underscores as digit separators. Whitespace is trimmed automatically.
Parameters: None
Returns: Float
Raises: Error if the string cannot be parsed as a float
Example:
# Decimal
puts("3.14".to_float()) # 3.14
puts("-2.5".to_float()) # -2.5
# Integers work too
puts("42".to_float()) # 42.0
# Scientific notation
puts("1e3".to_float()) # 1000.0
puts("1.5e2".to_float()) # 150.0
puts("2.5e-2".to_float()) # 0.025
# With underscores
puts("1_000.5".to_float()) # 1000.5
# With whitespace
puts(" 3.14 ".to_float()) # 3.14
# Error case
try
"not a number".to_float()
catch e
puts(e.message())
end
to_decimal() #
Converts a string to an arbitrary-precision decimal number. This is useful for financial calculations and other cases where exact decimal representation is required.
Parameters: None
Returns: Decimal
Raises: Error if the string cannot be parsed as a decimal
Example:
# High-precision decimals
let price = "19.99".to_decimal()
puts(price.to_string()) # 19.99
# Very precise values maintained
let precise = "0.12345678901234567890".to_decimal()
puts(precise.to_string()) # Maintains precision
# Negative decimals
let neg = "-99.99".to_decimal()
puts(neg.to_string()) # -99.99
# Whitespace trimmed
let d = " 12.34 ".to_decimal()
puts(d.to_string()) # 12.34
# Financial calculations
let subtotal = "100.00".to_decimal()
let tax = "8.75".to_decimal()
let total = subtotal.add(tax)
puts(total.to_string()) # 108.75
to_bigint() #
Converts a string to an arbitrary-precision integer (BigInt). Supports decimal, hexadecimal (0x), binary (0b), and octal (0o) formats. Can handle numbers larger than standard 64-bit integers. The trailing 'n' suffix (used in BigInt literals) is automatically stripped if present.
Parameters: None
Returns: BigInt
Raises: Error if the string cannot be parsed as a BigInt
Example:
# Large numbers
let big = "999999999999999999999999".to_bigint()
puts(big.to_string())
# Negative BigInt
let neg = "-123456789012345".to_bigint()
puts(neg.to_string()) # -123456789012345
# With 'n' suffix (compatible with literal syntax)
let b = "123n".to_bigint()
puts(b.to_string()) # 123
# Hexadecimal
let hex = "0xFFFFFFFFFFFFFFFF".to_bigint()
puts(hex.to_string()) # 18446744073709551615
# Binary
let bin = "0b11111111".to_bigint()
puts(bin.to_string()) # 255
# Octal
let oct = "0o777".to_bigint()
puts(oct.to_string()) # 511
# With underscores
let big_num = "1_000_000_000_000".to_bigint()
puts(big_num.to_string()) # 1000000000000
# Whitespace trimmed
let b = " 999 ".to_bigint()
puts(b.to_string()) # 999
# Error case
try
"123.45".to_bigint() # Error: BigInt doesn't accept decimals
catch e
puts(e.message())
end
Common Use Cases #
Parsing User Input #
# Get port number from environment or use default
let port_str = os.getenv("PORT") or "8080"
let port = port_str.to_int()
puts(f"Server listening on port {port}")
Configuration Parsing #
# Parse various configuration values
let config = {
"max_connections": "100".to_int(),
"timeout": "30.5".to_float(),
"price": "19.99".to_decimal(),
"user_id": "1234567890123456789".to_bigint()
}
Error Handling #
fun parse_port(value)
try
let port = value.to_int()
if port < 1 or port > 65535
return nil
end
return port
catch e
return nil # Invalid port string
end
end
let port = parse_port("3000") or 8080
ord() #
Returns the Unicode codepoint of the first character in the string.
Parameters: None
Returns: Int (Unicode codepoint)
Raises: Error if the string is empty
Example:
# ASCII characters
puts("A".ord()) # 65
puts("Z".ord()) # 90
puts("a".ord()) # 97
puts("0".ord()) # 48
# Special characters
puts(" ".ord()) # 32 (space)
puts("!".ord()) # 33
puts("\n".ord()) # 10 (newline)
# Unicode characters
puts("€".ord()) # 8364 (Euro sign)
puts("👍".ord()) # 128077 (Thumbs up emoji)
# Multi-character strings (takes first char)
puts("Hello".ord()) # 72 (H)
# Roundtrip with chr()
puts(chr("A".ord())) # A
# Character arithmetic
let shifted = chr("A".ord() + 3)
puts(shifted) # D (simple Caesar cipher)
# Empty string error
try
"".ord()
catch e
puts(e.message()) # ord requires non-empty string
end
See also: chr() global function for the inverse operation (codepoint to character).