Primitives
Primitives are fundamental types that just exist. These types cannot be expressed as composites of other types.
Bool
Booleans are represented by the Bool
type, which can take on the values
True
and False
.
let x = True
let y = False
Int
Integers are represented by the Int
type, which is an arbitrary precision
signed integer (commonly referred to as a bignum). By default, integers are
specified in decimal (base 10). Case-sensitive prefixes of 0b
for binary
(base 2), 0o
for octal (base 8), and 0x
for hexadecimal (base 16) may be
used. Underscores (_
) may appear anywhere in the literal except before the
first digit, after the last digit, and before, between, or after the characters
of the 0b
, 0o
, and 0x
prefixes. Multiple underscores may appear
consecutively.
0 50 1_000_000 // Decimal
0b10101010 0b1111_0110 // Binary
0o12345670 0o123_005_774 // Octal
0x1234567890abcdefABCDEF 0xfe_23_06 // Hexadecimal
1_2__3___4 // Multiple underscores may appear consecutively.
Float
A Float
is an IEEE 754 floating-point number with at least double precision
(i.e., 64 bits). A Float
literal must include either a .
or e
(or both)
to distinguish it from an integer literal. Underscores (_
) can be used to
separate digits and may appear anywhere in the literal except before the first
digit, after the last digit, immediately after the .
(radix point), and
before, between, or after the characters of the e
, e+
, and e-
.
0.0 23.45 1_057.1 3.141_593 // Regular
1e9 2.5e-4 2_712.349_753e+10 // Scientific
6___.7_8__9e4__5 // Excessive underscores for some reason.
String
A String
represents textual data encoded in UTF-8. String literals use double
quotes ("..."
) and may contain Unicode characters.
let s1 = "🍉 is a watermelon"
let s2 = "\u{1F349} is a watermelon"
assert_eq(s1, s2)
String escapes
Escapes are used to insert values that may not be ambiguous to express via
regular text. For example, \"
escapes the double quote and the resulting
value of this sequence is "
. There are several escapes that can be used.
\n
: Newline (U+000A).\r
: Carriage return (U+000D).\t
: Tab (U+0009).\\
: Backslash (\
).\0
: Null (U+0000).\'
: Single quote ('
).\"
: Double quote ("
).\u{XXXXXX}
: Unicode escape of up to 24 bits, where eachX
is a hex digit. There can be 1 to 6 hex digits in the curly braces.\x{XX}
: 1 byte where eachX
is a hex digit.\x{XXYY}
: 2 bytes where eachX
andY
is a hex digit. This is equivalent to\x{XX}\x{YY}
. In general, there may be arbitrarily manyX
s; however, there must be an even number of them to guarantee an integer number of bytes.
Strings spanning multiple lines
When a string spans multiple lines, all lines are joined by a space. Leading
whitespace on continuing lines, trailing whitespace on non-terminal lines, and
empty lines are ignored. Escapes such as \n
and \u{...}
are preserved.
// Strings spanning multiple lines are joined with a space.
let s1 = "apples
bananas cherries "
let s2 = "apples bananas cherries"
assert_eq(s1, s2)
Block strings
Block strings use three double quotes to delimit the start and end. The
following whitespaces are stripped: leading whitespace before the first
non-whitespace line of text, leading whitespace common to the start of each
line, trailing whitespace on each line, trailing whitespace after the last
non-whitespace line of text, and carriage returns (U+000D) are stripped.
Carriage returns included by an escape, such as \r
, are respected.
let s1 = """
text that
is spread
across
several lines
"""
let s2 = " text that\n is spread\nacross\n several lines"
assert_eq(s1, s2)
Raw strings
Raw strings are delimited with r"..."
and do not process any escapes. There
can be 0 or more #
between the r
and opening "
, and the same number of
#
must appear after the closing #
. Carriage returns (U+000D) are removed.
The same whitespace processing rules as
String
s enclosed in "..."
are applied.
assert_eq(r"no \n escapes", "no \\n escapes")
assert_eq(r#"nested r"raw" string "#, "nested r\"raw\" string")
Bytes
Bytes
are similar to strings but store arbitrary binary data. Bytes
literals look like String
literals with a b
prefix. Unlike a String
,
Bytes
may contain arbitrary binary data. Bytes
literals, however, can
consist of only ASCII literal characters. The \u{...}
and \x{...}
escapes
must be used to encode Unicode (or other character sets). The same
whitespace processing rules as String
s
enclosed in "..."
are applied to Bytes
.
let b1 = b"this is not
\x{FF}
valid Unicode"
let b2 = b"this is not \x{FF} valid Unicode"
assert_eq(b1, b2)
Raw bytes
Raw byte strings can also be constructed using the same rules as
raw strings, but with a br
prefix. The same
whitespace processing rules as String
s
enclosed in "..."
are applied.
assert_eq(br"no \n escapes", b"no \\n escapes")
assert_eq(br#"nested br"raw byte" string "#, b"nested br\"raw byte\" string")