Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

lib/string.x

Canonical byte strings and core text operations.

Primary API

FunctionSummary
String.addReturns str followed by other.
String.capitalizeUpper-cases the first byte of str and lower-cases the remainder.
String.containsReports whether the bytes of sub occur anywhere in str.
String.countReturns the non-overlapping count of sub in str.
String.endswithReports whether str ends with suffix.
String.filterReturns the bytes of str accepted by ordinary Var truthiness of fn.
String.findReturns the index of the first occurrence of sub in str, or -1.
String.find_allReturns each non-overlapping starting index at which sub occurs.
String.find_withinReturns the first index of sub within str[start:end], or -1.
String.getindexReturns the byte at index in str as an int, or -1 if out of range.
String.getsliceReturns the canonical String str[start:stop:step].
String.iterInitializes dest as a lazy iterator over the bytes of x.
String.joinJoins strings into one canonical String with sep between elements.
String.keepReturns a canonical String containing only bytes found in chars.
String.lenReturns the byte length of str, excluding the terminating NUL.
String.lowerReturns str with every upper-case byte lowered.
String.lstripRemoves leading bytes found in the C string negChars.
String.mapReturns str with fn applied to every byte.
String.newReturns the canonical String holding the bytes of the C string str.
String.pad_centerPads both sides of str to the requested width.
String.pad_leftPads the left side of str to the requested width.
String.pad_rightPads the right side of str to the requested width.
String.partitionSplits str at the first sep into a three-element List.
String.rejectReturns a canonical String after removing bytes found in chars.
String.remove_prefixRemoves prefix when str starts with it and returns a canonical String.
String.remove_suffixRemoves suffix when str ends with it and returns a canonical String.
String.repeatReturns a canonical String containing count copies of str.
String.replaceReturns str with every occurrence of old replaced by replacement.
String.replace_nReplaces at most max_replacements non-overlapping occurrences of old.
String.rfindReturns the index of the last occurrence of sub in str, or -1.
String.rpartitionSplits str around its final occurrence of sep.
String.rstripRemoves trailing bytes found in the C string negChars.
String.squeezeCollapses adjacent runs of each byte listed in chars.
String.startswithReports whether str starts with prefix.
String.stripReturns str with leading and trailing bytes in negChars removed.
String.unescapeDecodes supported backslash escapes in str into a canonical String.
String.upperReturns str with every lower-case byte raised.
String.withindexReturns a canonical copy of str with the byte at index set.
String.write_strAppends str to out unchanged.

String

String.add

String String.add(String str, String other)

Returns str followed by other. This implements the add row of protocol Var(String), so it is what + on two Strings lowers to, and because the result is interned, == on a newly built result is a content comparison. Either operand may be the empty String, in which case the other pointer is returned unchanged with its existing ownership and canonical or transient state.

Every concatenation interns its result, so building text by repeated concatenation in a loop allocates and hashes at every step. Use Buffer for that, or collect the pieces and call String.join once.

Raises: <size-limit> when the result cannot fit the String representation. Allocation failures propagate from the owning allocator.

Source: lib/string.x:635

String.capitalize

String String.capitalize(String str)

Upper-cases the first byte of str and lower-cases the remainder. Mapping is bytewise through C’s toupper and tolower. Null, empty, and unchanged inputs are returned as-is.

Raises: <alloc-fail> while constructing the result.

Source: lib/string.x:780

String.contains

int String.contains(String str, String sub)

Reports whether the bytes of sub occur anywhere in str. An empty sub is contained in every String, including the empty one, so a truth test on user-supplied text should check for emptiness separately if that matters.

Source: lib/string.x:590

String.count

int String.count(String str, String sub)

Returns the non-overlapping count of sub in str. A null or empty str or sub returns zero.

Source: lib/string.x:560

String.endswith

int String.endswith(String str, String suffix)

Reports whether str ends with suffix. An empty suffix is a suffix of every String. The comparison is bytewise, so this is a safe test for a file extension but not for a case-insensitive one; lower both sides first.

Source: lib/string.x:613

String.filter

String String.filter(String str, Func fn)

Returns the bytes of str accepted by ordinary Var truthiness of fn. Each byte is boxed from char and passed by value. A null or empty str, or a null fn, returns str without invoking the callback. Otherwise fn is called once per byte from left to right and is not retained.

Raises: whatever Func.apply, fn, or the returned Var’s truth operation raises, or <alloc-fail> when the result cannot be allocated.

Source: lib/string.x:858

String.find

int String.find(String str, String sub)

Returns the index of the first occurrence of sub in str, or -1. The search is byte-oriented rather than character-oriented, so an index may land inside a multibyte sequence. An empty sub matches at index 0. Use String.find_within to bound the search to a range, or String.rfind to scan from the end.

Source: lib/string.x:521

String.find_all

List String.find_all(String str, String sub, int start, int end)

Returns each non-overlapping starting index at which sub occurs. The search begins at start and uses the same normalized exclusive end as String.find_within. Null or empty str or sub returns nil. The result is a canonical List whose cells follow their owning pools.

Raises: <alloc-fail> or <size-limit> while constructing the result.

Source: lib/string.x:543

String.find_within

int String.find_within(String str, String sub, int start, int end)

Returns the first index of sub within str[start:end], or -1. The returned index is absolute, measured from the start of str rather than from start. Negative start and end count from the end of str, and both are then clamped to the String.

An end of -1 is the sentinel for “to the end of str”, not “one byte before the end”. There is therefore no negative end that excludes only the last byte; pass a nonnegative end for that. An empty sub matches at the normalized start.

String text = "abcabc";
printf("%d %d %d\n", text.find_within("c", 0, -1),
       text.find_within("c", 0, 2), text.find_within("a", -3, -1));

Source: lib/string.x:500

String.getindex

int String.getindex(String str, int index)

Returns the byte at index in str as an int, or -1 if out of range. This is what str[index] lowers to on a canonical String, and it yields a byte value rather than a one-byte String. A negative index counts from the end, so -1 is the last byte.

An index at or beyond the length is out of range.

Source: lib/string.x:579

String.getslice

String String.getslice(String str, int start, int stop, int step)

Returns the canonical String str[start:stop:step]. This is what slice syntax lowers to. stop is exclusive, negative start and stop count from the end, and a negative step walks backwards, so str[::-1] reverses. Indices are byte positions, so a slice can split a multibyte sequence. A full unit-step slice may return str; other nonempty slices return their canonical String.

Raises: <alloc-fail> while constructing a nonempty result. An empty range, a range that runs the wrong way for its step, or a step of zero also returns NULL, the empty String, without raising.

Source: lib/string.x:715

String.iter

Iter String.iter(String x, Iter dest)

Initializes dest as a lazy iterator over the bytes of x. The caller owns dest; it borrows x, which must remain live through traversal. A null dest returns NULL, and null x is exhausted. Each pull yields the next byte as an <i32> Var in index order. The function retains neither argument. Foreach may convert each yielded byte to either int or char:

foreach (int byte, %"abc") printf("%d\n", byte);
foreach (char ch, %"abc") printf("%c\n", ch);

This is byte traversal, not Unicode character iteration.

Source: lib/string.x:1461

String.join

String String.join(String sep, List strings)

Joins strings into one canonical String with sep between elements. The receiver is the separator, not the sequence, so this reads sep.join(parts). A null sep joins with nothing between elements. Empty elements contribute no bytes but still count as positions, so joining a split result with the same separator reproduces the original text, adjacent separators included. List elements that are not Strings convert to the empty String.

Raises: <alloc-fail> when result storage cannot be allocated. A null or empty List, or an oversized result, also returns NULL, the empty String, without raising.

Source: lib/string.x:1034

String.keep

String String.keep(String str, String chars)

Returns a canonical String containing only bytes found in chars. Null str returns NULL; null chars returns NULL for any nonnull input.

Raises: <alloc-fail> while constructing the result.

Source: lib/string.x:895

String.len

int String.len(String str)

Returns the byte length of str, excluding the terminating NUL. Constant time: the length is cached in the String’s private header. Lengths are bytes, not characters, so a multibyte UTF-8 sequence counts once per byte. On a transient String.malloc buffer this reports the writable byte count rather than the length of anything written so far.

The empty String is the null pointer, whose length is 0.

Source: lib/string.x:315

String.lower

String String.lower(String str)

Returns str with every upper-case byte lowered. Case mapping runs byte by byte through C’s tolower, so it covers ASCII in the default locale and leaves multibyte text alone rather than case-folding it. When no byte would change, str itself is returned after the unchanged temporary buffer is released.

Raises: <alloc-fail> while constructing the result.

Source: lib/string.x:761

String.lstrip

String String.lstrip(String str, char *negChars)

Removes leading bytes found in the C string negChars. Passing NULL uses " \t\n\v\f\r". The result is canonical; null input returns NULL and an unchanged input is returned as-is.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:789

String.map

String String.map(String str, Func fn)

Returns str with fn applied to every byte. Each byte is boxed from char and passed by value. Each result is checked and converted to int before byte assignment. A null or empty str, or a null fn, returns str without invoking the callback. Otherwise fn is called once per byte from left to right and is not retained. Each result must convert to a non-NUL byte.

Raises: whatever Func.apply, fn, or result conversion raises, <bad-result> when the converted result is zero, or <alloc-fail> when the result cannot be allocated.

Source: lib/string.x:873

String.new

String String.new(const char *str)

Returns the canonical String holding the bytes of the C string str. The input is borrowed and copied, so str may be a stack buffer and mutating it afterwards does not disturb the result. Equal nonempty content visible in the active pool chain yields the same pointer, which is why == on canonical Strings from that chain is a content comparison. A detached or sibling pool may hold a distinct equal pointer. Empty input canonicalizes to the null pointer, the empty String’s only representation.

Raises: <alloc-fail> when canonical storage cannot be allocated. A null, empty, or oversized input returns NULL, which is indistinguishable from the empty String, without raising.

Source: lib/string.x:445

String.pad_center

String String.pad_center(String str, int width, char fill)

Pads both sides of str to the requested width.

Raises: the same causes as String.pad_left.

Source: lib/string.x:954

String.pad_left

String String.pad_left(String str, int width, char fill)

Pads the left side of str to the requested width.

Raises: <bad-arg> when fill is NUL, <size-limit> when width cannot be represented, or <alloc-fail> when result storage cannot be allocated.

Source: lib/string.x:942

String.pad_right

String String.pad_right(String str, int width, char fill)

Pads the right side of str to the requested width.

Raises: the same causes as String.pad_left.

Source: lib/string.x:948

String.partition

List String.partition(String str, String sep)

Splits str at the first sep into a three-element List. The elements are the text before the separator, the separator itself, and the text after it. When sep does not occur, the result is str followed by two empty Strings, so the shape is three elements either way and a caller can destructure it without testing for the separator first. A leading separator and a missing separator both give an empty first element, so compare the middle element against sep if you need to tell them apart. The result and any new substrings are canonical and follow their owning List and String pools. Unchanged str and sep elements are borrowed into the result, so a transient input must outlive the returned List.

Raises: <alloc-fail> or <size-limit> while constructing the result.

Source: lib/string.x:991

String.reject

String String.reject(String str, String chars)

Returns a canonical String after removing bytes found in chars. Null or empty str, or null chars, returns str unchanged.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:906

String.remove_prefix

String String.remove_prefix(String str, String prefix)

Removes prefix when str starts with it and returns a canonical String. A null or absent prefix returns str unchanged; removing the complete String returns NULL.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:963

String.remove_suffix

String String.remove_suffix(String str, String suffix)

Removes suffix when str ends with it and returns a canonical String. A null or absent suffix returns str unchanged; removing the complete String returns NULL.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:973

String.repeat

String String.repeat(String str, int count)

Returns a canonical String containing count copies of str. Null or empty input, a nonpositive count, or an oversized result returns NULL. A count of one returns str when it is already visible in the active pool; a transient buffer is copied and interned instead.

Raises: <alloc-fail> while constructing a nonempty result.

Source: lib/string.x:659

String.replace

String String.replace(String str, String old, String replacement)

Returns str with every occurrence of old replaced by replacement. Scanning runs left to right and matches do not overlap: each one resumes after the text it consumed, so replacing aa in aaaa performs two replacements, not three. Replaced text is never rescanned, so a replacement that contains old does not loop. An empty replacement deletes the matches.

When there is nothing to replace, str itself is returned, so the result may be the same pointer as the input.

Raises: <alloc-fail> when result storage cannot be allocated. An empty or null old returns str, and an oversized result returns NULL, without raising.

Source: lib/string.x:1132

String.replace_n

String String.replace_n( String str, String old, String replacement, int max_replacements)

Replaces at most max_replacements non-overlapping occurrences of old. Scanning proceeds left to right and does not rescan replacement text. A negative limit replaces all matches; zero, null or empty old, null input, or no match returns str unchanged. Null replacement deletes matches. An oversized result returns NULL.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:1076

String.rfind

int String.rfind(String str, String sub)

Returns the index of the last occurrence of sub in str, or -1. Scanning runs backwards from the end, and the returned index still measures from the start of str. An empty sub reports the length of str, matching after the last byte and mirroring the forward search reporting 0.

Source: lib/string.x:529

String.rpartition

List String.rpartition(String str, String sep)

Splits str around its final occurrence of sep. The three elements are the text before the separator, the separator itself, and the text after it. When sep is null or absent, two empty Strings precede str. New substrings are canonical; the result follows its owning List and String pools. Unchanged str and sep elements are borrowed into the result, so a transient input must outlive the returned List.

Raises: <alloc-fail> or <size-limit> while constructing the result.

Source: lib/string.x:1011

String.rstrip

String String.rstrip(String str, char *negChars)

Removes trailing bytes found in the C string negChars. Passing NULL uses " \t\n\v\f\r". The result is canonical; null input returns NULL and an unchanged input is returned as-is.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:802

String.squeeze

String String.squeeze(String str, String chars)

Collapses adjacent runs of each byte listed in chars. Bytes outside chars are preserved even when repeated. Null or empty str, or null chars, returns str unchanged.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:916

String.startswith

int String.startswith(String str, String prefix)

Reports whether str starts with prefix. An empty prefix is a prefix of every String. String.remove_prefix performs the same test and returns the remainder, so there is rarely a reason to run both.

Source: lib/string.x:602

String.strip

String String.strip(String str, char *negChars)

Returns str with leading and trailing bytes in negChars removed. negChars is a NUL-terminated C string listing the bytes to remove, not a substring and not a pattern; order and repetition in it are irrelevant. Passing NULL uses the default whitespace set “ \t\n\v\f\r“. Trimming stops at each end on the first byte not in the set, and str itself is returned when nothing is trimmed.

Raises: <alloc-fail> while constructing the result. A String made entirely of removable bytes trims to NULL, the empty String, without raising.

Source: lib/string.x:820

String.unescape

String String.unescape(String str)

Decodes supported backslash escapes in str into a canonical String. Standard single-byte escapes, up to two hexadecimal digits after x, u, or U, and up to three octal digits are consumed. A backslash-newline is removed, an unknown escape yields its following byte, and a trailing backslash is dropped. Null input returns NULL and input without a backslash is returned unchanged.

Raises: <alloc-fail> while constructing a changed result.

Source: lib/string.x:1272

String.upper

String String.upper(String str)

Returns str with every lower-case byte raised. Like String.lower, mapping runs byte by byte through C’s toupper and covers ASCII in the default locale. str itself is returned when nothing would change.

Raises: <alloc-fail> while constructing the result.

Source: lib/string.x:771

String.withindex

String String.withindex(String str, int index, char value)

Returns a canonical copy of str with the byte at index set. Canonical Strings are immutable, so str is not modified. When the byte already has value, this may return str; otherwise a new String is built and interned. Native assignment str[index] = value writes through shared canonical storage and belongs only on a transient String.malloc buffer. A negative index counts from the end.

String word = "hello";
String capital = word.withindex(0, 'H');
printf("%s %s\n", word, capital);

Raises: <bad-arg> when value is NUL, which a String cannot contain, or <alloc-fail> while constructing the result. An out-of-range index returns str unchanged.

Source: lib/string.x:690

String.write_str

Buffer String.write_str(String str, Buffer out)

Appends str to out unchanged. A String is already its own display text, so this writes it directly instead of routing through String.str. Null str is a no-op. The borrowed out is returned and not retained.

Raises: any cause from Buffer.write.

Source: lib/string.x:1333

Advanced and interop API

FunctionSummary
String.compareCompares x and y bytewise, returning negative, zero, or positive.
String.equalReports whether x and y contain the same bytes.
String.escapeReturns a canonical escaped representation of the bytes in str.
String.freeReleases a transient String.malloc buffer early.
String.hashReturns the content hash of str, or zero for the empty String.
String.internReturns the canonical String for the borrowed bytes of string.
String.intern_freeFinalizes an owned String.malloc buffer into a canonical String.
String.mallocAllocates a transient mutable buffer of len bytes, not a String.
String.new_fillReturns the canonical String containing count copies of fill.
String.new_inReturns the canonical String for at most length borrowed bytes in pool.
String.new_lenReturns the canonical String holding at most len bytes of str.
String.parseReturns the canonical unescaped contents of str.
String.parse_charParses one leading single-quoted escaped or literal byte, or returns -1.
String.printfFormats a canonical String from fmt and the trailing arguments.
String.promoteMoves str from the active pool to its parent and returns the same pointer.
String.reprReturns a canonical quoted and escaped representation of str.
String.strReturns str itself as its display String without copying or retaining it.
String.symbolReturns the compact Symbol encoded from str, or zero for empty input.
String.write_reprAppends a quoted escaped representation of str to borrowed out.

String

String.compare

int String.compare(String x, String y)

Compares x and y bytewise, returning negative, zero, or positive. The ordering is C’s strcmp on the raw bytes, so it is neither locale-aware nor Unicode collation, and only the sign of the result is meaningful. The empty String, being the null pointer, sorts before every non-empty String, and two empty Strings compare equal.

Source: lib/string.x:1430

String.equal

int String.equal(String x, String y)

Reports whether x and y contain the same bytes. Interning already makes x == y a content test for two canonical Strings, so use this when one side may be a transient String.malloc buffer or when null has to compare cleanly. Two nulls are equal, since the null pointer is the empty String, and a null equals no non-empty String.

Source: lib/string.x:1418

String.escape

String String.escape(String str)

Returns a canonical escaped representation of the bytes in str. Common control and delimiter bytes use named escapes, printable ASCII is copied, and every other byte uses a three-digit octal escape. Null input or an oversized result returns NULL.

Raises: <alloc-fail> while constructing the result.

Source: lib/string.x:1299

String.free

void String.free(String str)

Releases a transient String.malloc buffer early. The pointer is first looked up in the intern table, including the enclosing pools, and the call does nothing if it is the canonical String visible from the active pool. Only a transient buffer allocated in the active pool chain is released; a canonical pointer from a detached or unrelated pool is not a valid argument.

A null argument is ignored.

Source: lib/string.x:294

String.hash

unsigned String.hash(String str)

Returns the content hash of str, or zero for the empty String. Canonical Strings use the cached hash; transient buffers are hashed from their current NUL-terminated contents.

Source: lib/string.x:1405

String.intern

Self String.intern(Self string)

Returns the canonical String for the borrowed bytes of string. This is String.new under another name. The bytes are copied into canonical storage and the caller keeps ownership of whatever buffer it passed in, so a stack array or a C library return value is a fine argument. It is not the finalizer for a String.malloc buffer: handing one here interns a second copy and leaves the buffer for the caller to free. Use String.intern_free for an owned buffer.

Raises: <alloc-fail> when canonical storage cannot be allocated. Null or empty input returns NULL, the empty String, without raising.

Source: lib/string.x:350

String.intern_free

Self String.intern_free(Self string)

Finalizes an owned String.malloc buffer into a canonical String. This takes ownership. The length and hash are computed from the buffer’s NUL-terminated contents, then the buffer either becomes the canonical String for that content or, when an equal canonical String already exists, is released in favor of the existing one. Either way the argument must not be used again; keep the return value. Passing an already canonical String visible in the active pool chain is a harmless no-op that returns it unchanged. The argument and its storage must be visible in that chain; a canonical String from a detached or sibling pool is not valid here because installing its pointer would outlive its storage.

String buf = String.malloc(6);
char *bytes = buf;
for (int i = 0; i < 5; i++) bytes[i] = 'a' + i;
String canonical = buf.intern_free();
printf("%s %d\n", canonical, canonical == "abcde");

Raises: <alloc-fail> when the canonical value cannot be registered. A null argument returns NULL, and a buffer empty at its first byte is released and reported as NULL, the empty String, without raising.

Source: lib/string.x:375

String.malloc

String String.malloc(int len)

Allocates a transient mutable buffer of len bytes, not a String. The byte count includes room for the terminating NUL, so len - 1 bytes are writable and String.len on a fresh buffer reports len - 1. The buffer is not interned and has no cached hash, so == against a canonical String is meaningless until it is finalized. Fill it with native indexing, then call String.intern_free to canonicalize and release it, or String.free to discard it. The backing allocation belongs to the active String/List pool and is invalidated when that pool is released, even though the caller controls finalization.

String buf = String.malloc(6);
printf("%d writable bytes\n", buf.len());
String.free(buf);

Raises: <alloc-fail> when storage cannot be allocated. A nonpositive or oversized len returns NULL without raising.

Source: lib/string.x:274

String.new_fill

String String.new_fill(char fill, int count)

Returns the canonical String containing count copies of fill. count must be less than INT_MAX, because the allocation includes one trailing NUL byte.

Raises: <bad-arg> when fill is NUL, or <alloc-fail> when canonical storage cannot be allocated. A nonpositive count returns NULL without raising.

Source: lib/string.x:476

String.new_in

String String.new_in(Pool pool, const char *bytes, int length)

Returns the canonical String for at most length borrowed bytes in pool. Copying stops at the first NUL. An existing equal String in pool or an ancestor is returned with that owner’s lifetime; otherwise the new value is owned by pool. A null argument, nonpositive length, or empty input returns NULL.

Raises: <alloc-fail>, <size-limit>, or <invariant> while interning.

Source: lib/string.x:61

String.new_len

String String.new_len(const char *str, int len)

Returns the canonical String holding at most len bytes of str. Copying stops at len bytes or at the first NUL, whichever comes first, because a String cannot carry embedded NUL bytes: String.new_len("ab\0cd", 5) is the two-byte String ab. str need not be NUL-terminated, so it may be bounded C input or a window into a larger buffer.

Raises: <alloc-fail> when canonical storage cannot be allocated. A null str, nonpositive len, or leading NUL returns NULL, the empty String, without raising.

Source: lib/string.x:462

String.parse

String String.parse(String str)

Returns the canonical unescaped contents of str. Matching outer %"..." or "..." delimiters are removed; unquoted input is unescaped directly. Null or empty input returns NULL. An unquoted input without backslashes is returned unchanged.

Raises: <alloc-fail> while copying or decoding.

Source: lib/string.x:1391

String.parse_char

int String.parse_char(String str)

Parses one leading single-quoted escaped or literal byte, or returns -1. The opening quote, one decoded byte, and a closing quote are required. Text after that closing quote is ignored. A decoded NUL is returned as zero; malformed and null input returns -1.

Source: lib/string.x:1356

String.printf

String String.printf(String fmt, ...)

Formats a canonical String from fmt and the trailing arguments. The receiver is the format String, so format-dependent construction reads %"%-12s %.2f".printf(name, score). Conversions, promotion rules, and argument matching are C’s, since the work is done by vsnprintf; canonical Strings are NUL-terminated and satisfy %s directly. Prefer %"$name has ${name.len()} bytes" when interpolation already says what you want.

Raises: <alloc-fail> when result storage cannot be allocated. An empty fmt or formatting error also returns NULL without raising. Arguments that do not match the conversions are undefined behavior as in C.

Source: lib/string.x:1146

String.promote

Self String.promote(Self str)

Moves str from the active pool to its parent and returns the same pointer. Empty, transient, and ancestor-owned Strings are returned unchanged.

Raises: <alloc-fail>, <size-limit>, or <invariant> while recording the promotion.

Source: lib/string.x:184

String.repr

String String.repr(String str)

Returns a canonical quoted and escaped representation of str. Empty input returns the canonical literal spelling "\"\"".

Raises: <alloc-fail> while escaping or formatting a nonempty String.

Source: lib/string.x:1322

String.str

String String.str(String str)

Returns str itself as its display String without copying or retaining it.

Source: lib/string.x:1316

String.symbol

Symbol String.symbol(String str)

Returns the compact Symbol encoded from str, or zero for empty input. Symbol’s restricted spelling folds case and _ with -; other spellings use seven-bit bytes, and input beyond the selected encoding’s capacity is truncated. Use Symbol.try_new when every byte must be preserved.

Source: lib/string.x:1379

String.write_repr

Buffer String.write_repr(String str, Buffer out)

Appends a quoted escaped representation of str to borrowed out. Bytes are streamed without first allocating an intermediate String. The same out is returned and not retained. Text written before a failure remains in the Buffer.

Raises: any cause from Buffer.write_char or Buffer.write_len.

Source: lib/string.x:1341

Runtime-internal callables

These callables connect runtime translation units. They are documented for source readers but are not supported as user API.

FunctionSummary
String.initializeInitializes the process-wide String runtime.
String.is_permanentAsks whether str already outlives every canonical String pool.
String.pool_currentReturns the borrowed active String/List pool on this thread.
String.pool_detachRemoves the active nested pool without destroying it.
String.pool_releaseReleases the current canonical-value pool for String.
String.pool_retainOpens the shared String and List canonical-value pool.
String.pool_retain_namedOpens and returns a named child of the active String/List pool.
String.shutdownReleases the canonical String pool during process shutdown.
String.thread_initializeInstalls the process String root in a newly created worker thread.
String.try_ownProves str safe beyond every active canonical String pool.

String

String.initialize

void String.initialize(void)

Initializes the process-wide String runtime.

Source: lib/string.x:115

String.is_permanent

int String.is_permanent(String str)

Asks whether str already outlives every canonical String pool. Returns 1 when str is empty or the outermost pool owns it, and 0 for a transient buffer or a String a nested pool can still reclaim. Unlike String.try_own it neither promotes nor allocates, so a caller may ask about a String it does not own.

Source: lib/string.x:209

String.pool_current

Pool String.pool_current(void)

Returns the borrowed active String/List pool on this thread.

Source: lib/string.x:102

String.pool_detach

Pool String.pool_detach(void)

Removes the active nested pool without destroying it. Thread keeps the detached pool sealed until join copies its survivors. The returned pool remains owned by the caller until that transfer or an explicit release.

Raises: <bad-state> when no nested pool is open. The failure leaves the active pool unchanged.

Source: lib/string.x:169

String.pool_release

void String.pool_release(void)

Releases the current canonical-value pool for String. Canonical Strings, Lists, and transient String buffers owned by that pool are reclaimed unless promoted; ancestor-owned values remain live.

Raises: <bad-state> when no nested pool is open. The failure leaves the active pool unchanged.

Source: lib/string.x:156

String.pool_retain

Pool String.pool_retain(void)

Opens the shared String and List canonical-value pool. List.pool_retain is another name for the same operation; callers open one bracket, not one through each name. New canonical misses enter the child, while equal ancestor values retain their existing owner. The caller must match this with one String.pool_release or detach it for transfer.

Raises: <alloc-fail> while opening the pool.

Source: lib/string.x:147

String.pool_retain_named

Pool String.pool_retain_named(const char *name)

Opens and returns a named child of the active String/List pool. New canonical misses enter the child; an equal ancestor value keeps its existing owner and lifetime. The caller must match this with one String.pool_release or detach it for transfer.

Raises: <alloc-fail> while opening the pool.

Source: lib/string.x:137

String.shutdown

void String.shutdown(void)

Releases the canonical String pool during process shutdown.

Source: lib/string.x:125

String.thread_initialize

void String.thread_initialize(void)

Installs the process String root in a newly created worker thread.

Source: lib/string.x:120

String.try_own

int String.try_own(String str)

Proves str safe beyond every active canonical String pool. Returns 1 when str is empty, already permanent, or can be promoted to the outermost pool. Returns 0 when no active pool owns it. Promotion proceeds one pool at a time; if a later step fails, the earlier promotions remain.

Raises: <alloc-fail>, <size-limit>, or <invariant> while recording a promotion.

Source: lib/string.x:198

Public types

TypeKindSummary
StringaliasAn immutable canonical NUL-terminated byte string, or NULL for empty.

String

typedef char *String

An immutable canonical NUL-terminated byte string, or NULL for empty. Equal nonempty contents visible in one String/List pool chain share a pointer. Assignment borrows that pointer; it does not copy or extend the owning pool’s lifetime. String.malloc is the mutable exception; its backing allocation still belongs to the active pool, and must be finalized with String.intern_free or released with String.free.

Source: lib/string.x:39

Design notes

A String is an immutable, interned, NUL-terminated byte sequence. Equal non-empty Strings visible in one pool chain have one canonical pointer; empty String is native zero. The private header owns exact byte length and a cached content hash.

String.malloc creates a transient mutable buffer in the active pool whose byte count includes room for the final NUL. Finish and release that buffer with String.intern_free; String.intern instead copies borrowed C input. String.free releases transient buffers early but leaves visible canonical Strings intact. Releasing the owning pool invalidates a transient buffer, and invalidates a canonical String unless it was promoted. A canonical String may instead belong to an ancestor pool.

Strings cannot contain embedded NUL bytes and do not claim Unicode character semantics. Case, classification, indexing, slicing, padding, escaping, and iteration operate on bytes.

Constructing or interning a nonempty canonical String may raise <alloc-fail>, <size-limit>, or <invariant> through pool storage and registration. These causes transfer and do not return to the operation.

Tests and examples

make verify (unittest/test-string.x) and make examples (docs-word-count).