Skip to content

gab has two string-like types: gab\string and gab\binary. A third type, gab\message, also belongs to this family. All three share their character data in memory. For example, the bytes [ 't', 'r', 'u', 'e' ] are stored once on the heap, shared between the string "true" and the message true:. Converting between these types is therefore a constant-time operation with no allocation.

gab\string

Strings are UTF-8 encoded byte sequences. Single-quoted strings support escape sequences; double-quoted strings do not.

"Hello!"
'\tHello\n'
'Hello \u[2502]'

Because gab respects UTF-8 encoding, operations that are constant-time on raw bytes may be linear-time on strings. For example, slicing a gab string at a given index requires scanning from the start, since utf8 codepoints may be anywhere from 1 to 4 bytes wide.

smiley := '😀'

smiley.len    #  1  (one codepoint)

Note

Computing the length of a utf-8 string is also linear-time. However, gab calculates this once and caches it - amoritizing the cost over time.

Constructing strings:

Strings.make('Ada', ' ', last_name)

'Format a value: $'.sprintf({ name: 'bob' })
#  'Format a value: { name: bob }'

sprintf replaces each $ in the format string with the corresponding argument, in order.

gab\binary

gab\binary operates on raw bytes with no encoding enforced. Indexing and slicing are constant-time because there is no encoding enforced upon the data.

There is no literal syntax for binaries. Convert a string with to\binary:

smiley     := '😀'
smiley_bin := smiley.to\binary

smiley.len      #  1  (codepoints)
smiley_bin.len  #  4  (bytes)

Slicing a binary is constant-time:

"This is a string".slice(3, 8)        # Linear — scans from start
"This is a string".to\binary.slice(3, 8)   # Constant time — byte offset

Converting a binary back to a string can fail if the bytes are not valid UTF-8:

(status, str) := some_binary.as\string

Tip

Note the difference between an as\<some_type> message and a to\<some_type> message:

The to\<some_type> family do not fail. This is a conversion guaranteed to succeed, or panic with an unrecoverable error.

The as\<some_type> family may fail. They try to interpret the receiver as some type, and may fail to do so. They return an error gracefully in such cases.

Shared memory with gab\message

Because gab\string, gab\binary, and gab\message all share the same underlying character data, converting between them is zero-cost. The string 'true' and the message true: occupy the same bytes — they differ only in their type tag.

'true'.to\message   #  true:   (no allocation)
true:.to\string    #  'true'  (no allocation)

This design means message values are just as efficient as strings in any context where they appear as keys or identifiers.