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/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.dedentRemoves the indentation the text was written with.
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 s[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.try_nextWrites the next byte, advances cursor, and returns one.
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/building.x:18

String.capitalize

meta native 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/mapping.x:54

String.contains

meta native 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/search.x:119

String.count

meta native 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/search.x:96

String.dedent

meta native String String.dedent(String str)

Removes the indentation the text was written with. The prefix is the run of spaces and tabs that opens the first content line, after one leading newline is dropped. Every following line that starts with that prefix loses exactly it, so indentation written past the prefix survives and the block renormalizes as a unit. A line that does not carry the prefix, including a blank one, is left alone, except that a final line of only spaces and tabs is removed so the closing quote’s own indentation does not reach the result. \r\n is preserved because only the prefix after a newline is removed.

Raises: <alloc-fail> while constructing a changed result. Null input returns NULL and text with no prefix is returned as-is.

Source: lib/string/splitting.x:62

String.endswith

meta native 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/search.x:142

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 returns str without invoking the callback. Otherwise fn is called once per byte from left to right and is not retained. A null fn raises <bad-arg> on the first invocation.

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/mapping.x:81

String.find

meta native int String.find(String str, String sub)

Returns the index of the first occurrence of sub in str, or -1. The search compares bytes, 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/search.x:10

String.find_all

meta native 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/search.x:81

String.find_within

meta native 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 and counts from the start of str. 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/search.x:29

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, so indexing yields an int byte value. A negative index counts from the end, so -1 is the last byte.

The byte is unsigned, so the result is 0 through 255 on every platform and -1 means out of range and nothing else. An index at or beyond the length is out of range.

Source: lib/string/editing.x:83

String.getslice

meta native String String.getslice(String s, int start, int stop, int step)

Returns the canonical String s[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 s[::-1] reverses. Indices are byte positions, so a slice can split a multibyte sequence. A full unit-step slice may return s; 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/editing.x:99

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/adapters.x:44

String.join

meta native 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/building.x:83

String.keep

meta native 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/mapping.x:119

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 count bytes, so a multibyte UTF-8 sequence counts once per byte. On a transient String.malloc buffer this reports the writable byte count.

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

Source: lib/string/storage.x:43

String.lower

meta native 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 does not case-fold multibyte text. 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/mapping.x:35

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/splitting.x:29

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 converted to int and truncated to the byte that is stored, and that byte is what is checked, so a result such as 256 raises because its stored byte would be NUL. A null or empty str 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. A null fn raises <bad-arg> on the first invocation.

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/mapping.x:99

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/storage.x:100

String.pad_center

meta native 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/building.x:146

String.pad_left

meta native 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/building.x:134

String.pad_right

meta native 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/building.x:140

String.partition

meta native 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 gives an empty first element and a missing separator gives two empty trailing elements, 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/splitting.x:117

String.reject

meta native 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/mapping.x:130

String.remove_prefix

meta native 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/splitting.x:89

String.remove_suffix

meta native 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/splitting.x:99

String.repeat

meta native 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/building.x:42

String.replace

meta native 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/editing.x:18

String.replace_n

meta native 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/editing.x:29

String.rfind

meta native 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/search.x:67

String.rpartition

meta native 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/splitting.x:137

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/splitting.x:42

String.squeeze

meta native 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/mapping.x:140

String.startswith

meta native 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/search.x:131

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/splitting.x:15

String.try_next

int String.try_next(String str, int &?cursor, int &?out)

Writes the next byte, advances cursor, and returns one. Initialize the caller-owned cursor to zero. A null String, a null pointer, a negative cursor, or exhaustion returns zero without changing cursor or out. This is byte traversal, not Unicode characters.

foreach (int byte, str) and foreach (char ch, str) compile to this loop.

Source: lib/string/adapters.x:65

String.upper

meta native 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/mapping.x:45

String.withindex

meta native 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/editing.x:127

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/adapters.x:16

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.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.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.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

String.compare

meta native 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/storage.x:78

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/storage.x:66

String.free

meta native 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/storage.x:302

String.hash

meta native 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/storage.x:53

String.intern

meta native 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/storage.x:149

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/storage.x:246

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/storage.x:213

String.new_fill

meta native String String.new_fill(char fill, int count)

Returns the canonical String containing count copies of fill.

Raises: <bad-arg> when fill is NUL, <size-limit> when count is INT_MAX, because the allocation includes one trailing NUL byte, or <alloc-fail> when canonical storage cannot be allocated. A nonpositive count returns NULL without raising.

Source: lib/string/building.x:62

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. The active pool does not change. 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/storage.x:132

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/storage.x:117

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, and String.format when the arguments must be checked.

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/building.x:177

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/storage.x:325

String.str

String String.str(String str)

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

Source: lib/string/adapters.x:8

String.symbol

meta native 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/adapters.x:23

Runtime-internal callables

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

FunctionSummary
String.is_permanentAsks whether str already outlives every canonical String pool.
String.try_ownProves str safe beyond every active canonical String pool.

String

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/storage.x:350

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/storage.x:339

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/string.x:29

Design notes

String owns canonical immutable byte strings. Equal nonempty contents in one pool chain share one pointer, the empty String is native zero, and a private header before the bytes holds the exact length and a cached content hash. A String cannot hold an embedded NUL, and every operation here works on bytes, without Unicode character semantics.

A canonical String belongs to the pool that interned it or to an ancestor, and releasing that pool invalidates it unless it was promoted. A transient String.malloc buffer belongs to the active pool until it is interned or freed. Pool storage and registration causes transfer and never return to the constructing operation.

Tests and examples

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