Popup YouTube Video
Sheerpower Logo

String Manipulation Functions and Features


Sheerpower provides a large set of high-performance string functions. String expressions are evaluated at compile time (constant folding) when they involve only literals, so there's no runtime cost for building common patterns.

Problem: Rebuilding the same strings at runtime wastes time and work.

Solution: Constant folding precomputes eligible string expressions during compilation (e.g., concatenations of literals). The generated code uses the precomputed result directly.

Efficiency: Zero runtime overhead for those expressions, fewer allocations, and tighter loops.

Takeaway: Write naturally. If an expression is composed only of literals, the compiler precomputes it.
// Examples (precomputed at compile time) U$ = charset$("ucase") // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" T$ = "User: " + "ADMIN" // "User: ADMIN" // Runtime work happens only when variables enter the expression: prefix$ = "User: " name$ = input_name$ // variable print prefix$ + name$ // evaluated at runtime

Three Layers of String Speed

Constant folding is the first of three optimizations that work together, and each one targets a pattern people naturally write — so the natural way to write string code is the fast way:

  • Constant folding (compile time) — every all-literal part of an expression is computed once, by the compiler, and the program carries the finished text.
  • Concat-gather (runtime) — a chain of + with variables in it is built in a single allocation, however many pieces it has, rather than making and discarding an intermediate string at every +.
  • The append accumulator (loops) — s$ = s$ + piece$ grows s$ in place with room to spare, so collecting a large result piece by piece stays cheap all the way up.

One REST call shows all three at once. The header expression below is three literals and one variable: the compiler folds the literals into a single string, so at runtime the whole line is one two-piece gather — <folded text> + key$ — and the reply loop is the accumulator:

// folded at compile time: 'Content-Type: application/json' + chr$(10) + 'Authorization: Bearer ' // gathered at runtime: that one literal + key$ hdrs$ = 'Content-Type: application/json' + chr$(10) + 'Authorization: Bearer ' + key$ open file api_ch: name 'http-post://' + quote$(url$), data payload$, headers hdrs$ reply$ = '' do line input #api_ch, eof done?: rec$ if done? then exit do reply$ = reply$ + rec$ // append accumulator: grows in place loop close #api_ch

Nothing here asks you to think about performance. Write the clear version — literals where they belong, a plain + chain, a plain accumulating loop — and each line lands on its fastest path.


In business applications, strings are a fundamental data type used to represent and manipulate text—customer names, product descriptions, transaction details, and log entries. Because strings are everywhere, the performance of string operations can noticeably affect overall system efficiency.

Sheerpower's Focus on String Efficiency:

Sheerpower understands the importance of strings in business applications and has optimized its language to handle string operations with speed and efficiency. Whether it's searching, comparing, concatenating, or transforming strings, Sheerpower ensures that these operations are executed with minimal overhead.

Strings as buffers Strings can also be used to store data into fixed length buffers. Over 30 million string overlays can be processed per second on a modern PC.
For example:
mybuf$ = space$(1024) subtext$ = 'abcde' start_pos = 1 for idx = 1 to 5 start_pos = overlay(mybuf$, subtext$, start_pos) next idx

For higher-speed string bulding, Sheerpower includes the JOIN() function. the format is:
new_pos = join(string_var$, string1$, string2$, ...) up to 15 strings at a time.
numbers$ = '' for i = 1 to 100_0000 newlen = join(numbers$, str$(i), ' ') next i print 'Length: '; len(numbers$) print 'Elapsed: '; _elapsed

String Function Documentation

Description:
The ASCII() function returns the decimal ASCII value of the first character in str_expr.

Arguments:
str_expr (required): The string whose first character's ASCII value is to be returned.

Example:
print ascii('A')
Output: 65

Description:
The BASE64ENCODE$() function encodes the provided text string str_expr into Base64 format. By default, it inserts a newline (CR/LF) every 76 characters. An optional boolean parameter can be used to control whether the newline is inserted.

Arguments:
str_expr (required): The string to be encoded.
boolean (optional): Set to FALSE to prevent the insertion of newlines. Defaults to TRUE.

Example 1: Simple Base64 encoding
print base64encode$('What is the base64 encoded version of this sentence?')
Output: V2hhdCBpcyB0aGUgYmFzZTY0IGVuY29kZWQgdmVyc2lvbiBvZiB0aGlzIHNlbnRlbmNlPw==

Example 2: Encoding with whitespace
print base64encode$(' Man ')
Output: ICAgIE1hbiA=

Example 3: Encoding without whitespace
print base64encode$('Man')
Output: TWFu

Example 4: Encoding with CRLF inserted
print base64encode$(repeat$('Hi there ', 50), true)
Output:
SGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhl
cmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkg
dGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUg
SGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhl
cmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkg
dGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUg

Example 5: Encoding without CRLF inserted
print base64encode$(repeat$('Hi there ', 50), false)
Output:
SGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhl
cmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkg
dGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUg
SGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhl
cmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkg
dGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUgSGkgdGhlcmUg

Description:
The BASE64DECODE$() function decodes a Base64 encoded string str_expr back into its original plain text format. To encode a string into Base64, see the BASE64ENCODE$() function.

Arguments:
str_expr (required): The Base64 encoded string to decode.

Example 1: Decoding a Base64 string
print base64decode$('V2hlbiBvbmUgZG9vciBjbG9zZXMsIGFub3RoZXIgb3BlbnM7IGJ1dCB3ZSBvZnRlbiBsb29rIHNv' +
'IGxvbmcgYW5kIHNvIHJlZ3JldGZ1bGx5IHVwb24gdGhlIGNsb3NlZCBkb29yIHRoYXQgd2UgZG8g' +
'bm90IHNlZSB0aGUgb25lIHdoaWNoIGhhcyBvcGVuZWQgZm9yIHVzLiAtQWxleGFuZGVyIEdyYWhh' +
'bSBCZWxs')

Output:
When one door closes, another opens; but we often look so long and so regretfully
upon the closed door that we do not see the one which has opened for us. -Alexander Graham Bell

Example 2: Decoding a short Base64 string
a$ = 'c3VyZQ=='
b$ = base64decode$(a$)
print b$
Output: sure

Description:
The BETWEEN$() function returns the string value between str_expr2 and str_expr3. If str_expr2 is empty, the function assumes the beginning of str_expr1. If str_expr3 is empty, the function assumes the end of str_expr1.

Arguments:
str_expr1 (required): The string to search within.
str_expr2 (required): The substring marking the start of the extraction.
str_expr3 (required): The substring marking the end of the extraction.
int_occurrence (optional): Occurrence so you can iterate.

Returns:
The substring found between str_expr2 and str_expr3
A null string ("") if either str_expr2 or str_expr3 cannot be found in str_expr1 for the specified occurrence.

Example:
a$ = between$('the house was red', 'the ', ' was')
Output: 'house'
b$ = between$('size=30', '', '=')
Output: 'size'
c$ = between$('size=30', '=', '')
Output: '30'

Practical Uses:

  • Extracting Parameter Values from URLs:
    id_value$ = between$('http://example.com/page?id=1234&name=John&zip=98765', '=', '&', 1)
    Result: '1234'
    id_value$ = between$('http://example.com/page?id=1234&name=John&zip=98765', '=', '&', 2)
    Result: '98765'
  • Parsing Log Entries:
    error_code$ = between$('ERROR[code=404]: Not Found', '[code=', ']')
    Result: '404'
  • Processing Formatted Data:
    size_value$ = between$('size=30', '=', '')
    Result: '30'
  • Extracting Substrings in Text Parsing:
    book_name$ = between$('The title of the book is [Moby Dick]', '[', ']')
    Result: 'Moby Dick'

Related Statement: VIEW Using Delimiters (Dynamic BETWEEN)

The extended VIEW syntax allows you to create a dynamic slice of a string variable using start and end delimiters, just like BETWEEN$() — except the result is a live view instead of a copied string.

This makes it the dynamic counterpart to BETWEEN$(), just as the original VIEW ... position/length is the dynamic counterpart to MID$().

Syntax

VIEW view_var$ INTO base_var$ BETWEEN start_delim$, end_delim$

How it works:

  • The statement searches base_var$ for start_delim$ and end_delim$.
  • If start_delim$ is empty, the beginning of base_var$ is assumed.
  • If end_delim$ is empty, the end of base_var$ is assumed.
  • Instead of returning a copied substring, the view variable points directly into the section of base_var$ between the two delimiters.
  • If the delimiters are not found, the view becomes an empty string.
Note:
  • This form of VIEW creates a read-only view except for overlay operations (LSET, OVERLAY()), which modify the corresponding characters in base_var$.

    The view treats delimited regions of the string as live fields. When the base string is modified, the delimited region is re-located automatically the next time the view variable is referenced. If the delimiters are no longer present, the view evaluates to an empty string and _integer is set to zero.

    Because the view points directly into the base string, overlay operations update the underlying text in place, without copying, reallocating, or rebuilding the string.

  • When base_var$ is assigned a new value, the view does not immediately recalculate its start and end positions. Instead, the delimiters are re-evaluated the next time the view variable is referenced. This guarantees that the view always reflects the current contents of base_var$. For example, if base_var$ is later set to the null string, then on the next reference every view derived from it will also evaluate to a null string.

    When the view is referenced, the special variable _integer is set to the character position immediately following the ending delimiter, or to -1 if the delimiters were not found.

  • If the characters in base_var$ shift — for example, due to editing, concatenation, or overlay operations — the view will locate the delimiters again when the view is next used. This guarantees the view reflects the correct, live region of the modified string.
  • The view statement is executable, so any of its expression arguments can be changed at runtime. When evaluated, it updates the corresponding view_var$ when the variable is next referenced.

VIEW Options

  • MATCH — By default, the search uses the first occurrence of the start delimiter paired with the next occurrence of the end delimiter. With MATCH, Sheerpower instead returns the Nth such matching pair. MATCH is highly optimized; ten million sequential matches per second is typical on a modern laptop.
  • NOTRIM — By default, the substring between the delimiters is trimmed of leading and trailing spaces before it is returned or exposed via the view. Use NOTRIM to preserve the exact characters between the delimiters, including any surrounding whitespace.
  • BALANCED — By default, the search uses the first occurrence of the start delimiter and the very next occurrence of the end delimiter. With BALANCED, the engine instead finds the outer delimited region: starting at the first start delimiter and locating the matching closing delimiter that encloses the full region, including any nested or inner delimiters.

VIEW Example

data$ = "phone=(702) 555-1212 age=42" VIEW area$ INTO data$ BETWEEN "(", ")" VIEW age$ INTO data$ BETWEEN "age=", "" print area$ // Output: 702 print age$ // Output: 42 // Replace the entire base string data$ = "My new phone number is (858) 555-1212" // The view updates automatically print area$ // Output: 858 print age$ // Output: (empty string) // Overlay through the view modifies the source lset area$ = "211" print data$ // Output: My new phone number is (211) 555-1212 // Using MATCH to get a specific occurrence data$ = "phone=(702) 555-(1212) age=42" VIEW area2$ INTO data$ BETWEEN "(", ")" MATCH 2 print area2$ // Output: 1212 data$ = "phone=555-1212 age=42" // Missing parens print area2$ // Output: (empty string) // All VIEW parameters accept runtime expressions list$ = "[apple][banana][cherry]" for occurrence = 1 to 10 VIEW item$ INTO list$ BETWEEN "[", "]" MATCH occurrence if item$ = "" then exit for // No more items print item$ next occurrence // Output (one per line): // apple // banana // cherry // Automatic zero-copy parsing into cluster fields upon reference cluster info: name$, age$, weight$ view info->name$ into data$ between "name=" , ";" view info->age$ into data$ between "age=" , ";" view info->weight$ into data$ between "weight=", ";" data$ = 'name=Fred; age=45; weight=160;' print cluster info // outputs all field values in the cluster called info. data$ = 'weight=120; age=25; name=Sally; ' print cluster info // outputs: // "Fred","45","160" // "Sally","25","120"

Example: Using NOTRIM to Preserve Whitespace

// Base string with padded value data$ = "value=[ 123 ] status=ok" // Default: trims spaces between delimiters VIEW num$ INTO data$ BETWEEN "[", "]" // NOTRIM: keeps the exact characters between delimiters VIEW num_raw$ INTO data$ BETWEEN "[", "]" NOTRIM print "[" + num$ + "]" // Output: [123] print "[" + num_raw$ + "]" // Output: [ 123 ]

Example: Using BALANCED for Outer Delimited Region

data$ = "outer[start [inner] tail] end" // Without BALANCED: first "[" to first "]" after it VIEW inner$ INTO data$ BETWEEN "[", "]" // With BALANCED: first "[" to its matching outer "]" VIEW outer$ INTO data$ BETWEEN "[", "]" BALANCED print inner$ // Output: start [inner print outer$ // Output: start [inner] tail

Behavior Summary

Feature BETWEEN$() VIEW ... BETWEEN
Mechanism Returns a copy Creates a live view
Updates with base changes? No Yes, automatically
Memory Allocates new string No allocation; points to base
Write-through No Yes, using OVERLAY/LSET

Description:
The CHANGE$() function replaces characters in str_expr1 found in str_expr2 with the corresponding characters in str_expr3.

Arguments:
str_expr1 (required): The original string.
str_expr2 (required): The characters to be replaced.
str_expr3 (required): The replacement characters.

Example:
print change$('bdbdbdbd', 'b', 'c')
Output: cdcdcdcd

Description:
The CHARSET$() function returns a named character set. Available sets: UCASE, LCASE, DIGITS, CONTROL, PRINTABLE, ASCII7, and BYTE (alias: ASCII). Names are case-insensitive.

Arguments:
str_expr (optional): The character set to return. Default is BYTE.

Character Sets & ASCII Ranges:

  • UCASEA—Z (ASCII 65—90)
  • LCASEa—z (ASCII 97—122)
  • DIGITS0—9 (ASCII 48—57)
  • CONTROL — ASCII 0—31, 127 (includes DEL)
  • PRINTABLE — ASCII 32—126 (space through tilde)
  • ASCII7 — ASCII 0—127 (7-bit set)
  • BYTE (or ASCII) — ASCII 0—255 (full 8-bit set)

CHARSET$() is often paired with CHANGE$() for character filtering. The third parameter to CHANGE$() defaults to the empty string, so matched characters are removed.

Examples:

text$ = chr$(5) + "hi" + chr$(9) print "["; change$(text$, charset$("control")); "]"

Output: [hi]

print charset$("ucase")

Output: ABCDEFGHIJKLMNOPQRSTUVWXYZ

Description:
The CHR$() function returns a string of ASCII characters corresponding to int_expr1. If int_expr2 is provided, the character is repeated that many times.

Arguments:
int_expr1 (required): The ASCII value of the character.
int_expr2 (optional): The number of times to repeat the character.

Example:
print chr$(65)
Output: A

Description:
The CONVERT$() function converts an integer int_expr1 into a string. An optional length int_expr2 can be specified, which defaults to four. The int_expr3 argument specifies the data type of the conversion. The supported data types are:

Data Types:

Data TypeConversion Result
1Integer (2 or 4 byte)
7COBOL comp-3 (C3 packed decimal)
17Packed floating (PF)

Arguments:
int_expr1 (required): The integer to convert.
int_expr2 (optional): The length of the resulting string.
int_expr3 (optional): The data type for conversion.

Example: Convert an integer to a string
a$ = convert$(16961)
print a$
Output: AB

Description:
The CONVERT() function converts a string that represents a mapped integer value back into its numeric form.

The optional int_flag argument controls how the resulting integer is interpreted.

Arguments:
str_expr (required)
  The string containing the mapped integer representation.

int_flag (optional bit flag)
  Bit 1 (value 1) — Return a signed integer.
  Bit 3 (value 4) — Interpret the string as big-endian byte order.

(Show/Hide Endian Explanation)

Flags may be combined using addition.
For example:

  • 1 — signed integer
  • 2 — unused
  • 4 — big-endian integer
  • 1+4 — signed big-endian integer

If int_flag is omitted, the default behavior is unsigned, little-endian interpretation.
This matches the native byte order used by x86 processors.

Example:

// 'A' (0x41), 'B' (0x42) print convert('AB') // Default (Little-endian): 0x4241 Output: 16961 print convert('AB', 4) // Big-endian: 0x4142 Output: 16706

Description:
The CPAD$() function pads a string on both sides with a specified character to reach a given size.

Arguments:
text_str (required): The string to pad.
size (required): The desired size of the final string.
pad_str (optional): The character to use for padding. Default is a space.

Example:
print cpad$('123', 9, '0')
Output: 000123000

Description:
The EDIT$() function performs one or more editing operations on the supplied string argument, depending on the value of the integer expression int_expr. The operations are determined by the values listed below. You can combine multiple operations by adding their corresponding values together.

Operation Values:

ValueEdit Operation
1Trim parity bits.
2Discard all spaces and tabs.
4Discard characters: CR, LF, FF, ESC, RUBOUT, and NULL.
8Discard leading spaces, control characters and DEL (ASCII 127).
16Reduce multiple spaces and tabs to one space.
32Convert lower case to upper case.
64Convert "[" to "(" and "]" to ")".
128Discard trailing spaces, control characters and DEL (ASCII 127).
256Do not alter characters inside quotes.

Arguments:
str_expr (required): The string to edit.
int_expr (required): The integer specifying the editing operation(s).

Example:
print edit$('hi there, how are you today?' , 32)
Output: HI THERE, HOW ARE YOU TODAY?

Description:
The ELEMENTS() function returns the number of elements in str_expr1, with elements separated by str_expr2 (default is a comma). The ELEMENT$() function returns a specific element from str_expr1 as specified by num_expr.

Arguments:
str_expr1 (required): The string containing the list of elements.
str_expr2 (optional): The separator between elements. Default is a comma.
num_expr (required for ELEMENT$): The index of the element to return.

Example:
print elements('a,b,c', ',')
Output: 3
print element$('a,b,c', 2)
Output: b

Description:
The ELEMENT$() function returns the element from str_expr1 specified by num_expr. The string str_expr1 contains a set of elements with separators between them. The optional str_expr2 specifies the separator between elements; if omitted, a comma is used as the default separator.

Arguments:
str_expr1 (required): The string containing the list of elements.
num_expr (required): The element number to return.
str_expr2 (optional): The separator between elements (default: comma).

Example 1: Get the 2nd element from a comma-separated list
let a$ = element$('ADD,DEL,EXIT', 2)
print a$
Output: DEL

Example 2: Use a space as the separator
let sentence$ = 'This is a test.'
let a$ = element$(sentence$, 2, ' ')
print a$
Output: is

Example 3: Handle multiple separators in a row
let sentence$ = 'This,, is, a, test'
print element$(sentence$, 2)
Output: [null]

Description:
The ENCODE$() function converts a number to a string in a specified base (e.g., binary, hexadecimal).

Arguments:
num_expr (required): The number to encode.
num_int (required): The base to convert to (e.g., 2 for binary, 16 for hexadecimal). Bases two through 36 are supported.

Example:
print encode$(255, 16)
Output: FF

Description:
For a detailed description, see FILEINFO$() and FINDFILE$() File Related Functions.

Arguments:
filename_str (required): The file name.

items_str: A comma separated list of requested items. 'Contents' returns the contents of the file.

Example:
print fileinfo$('@myfile.txt', 'device,name')
Output: c:myfile

Description:
The FORMAT$() function formats a given expression according to the specified format string str_expr. The expression can be of any data type, including strings.

Details:
The '@' format character causes the character not to be translated by the formatter.
The '<' and '>' characters are treated like an '@' character.
The FORMAT$() function can justify a character string, but zero suppression and zero insertion should be avoided.
If an overflow occurs, FORMAT$() returns a string of asterisks '*'.

Arguments:
expr (required): The expression to be formatted.
str_expr (required): The format string that specifies how to format the expression.

Example 1: Formatting a phone number
z$ = format$('5551234567', '(###)###~-####')
print 'Phone number: '; z$
Output: (555)123-4567

Example 2: Handling overflow
z$ = format$(12.23,'#.##')
print z$
Output: ****

Special Formats:
FORMAT$() supports the DATE format and date arguments. Given a date in YYMMDD or CCYYMMDD format, FORMAT$() returns the date in the specified format.

Example 3: Formatting a date
z1$ = format$('990122', '{date mdcy}?')
z2$ = format$('990122', '{date mdcy}##/##/####')
z3$ = format$('20000122', '{date mdcy}?')
z4$ = format$('20000122', '{date mdcy}##/##/####')
print z1$, z2$
print z3$, z4$
Output:
01221999 01/22/1999
01222000 01/22/2000

Date Arguments:

DATE ArgumentYYMMDD Input ResultCCYYMMDD Input Result
none1213199912132020
YMD991213201213
CYMD1999121320201213
MDY121399121320
MDCY1213199912132020
DMY131299131220
DMCY1312199913122020
DMONY13-Dec-9913-Dec-20
DMONCY13-Dec-199913-Dec-2020
MONTHDYDecember 13, 99December 13, 20
MONTHDCYDecember 13, 1999December 13, 2020

Special Features:
FORMAT$() also supports character rotation. The {ROTATE n} option rotates the last n characters of a string to the first position in the string.
FORMAT$(z$, '{ROTATE n}?')
The ? can be replaced with a mask.

Description:
The FRACTION$() function converts num_expr to a string written as a reduced fraction, p/q. A value that a divide of two whole numbers kept exact (the RATIONAL mode) shows that fraction; a decimal shows the fraction it sits on; a whole value prints plain, with no /1. STR$() of the same value gives the decimal.

Arguments:
num_expr (required): The number to convert.

Example:
print fraction$(22 / 7)
Output: 22/7
print fraction$(0.25)
Output: 1/4
print fraction$(3)
Output: 3

See also FRACTION(), NUMERATOR(), DENOMINATOR() and DECIMAL(), and the Exact Fractions page (Exact Fractions: the RATIONAL Mode).

Description:
The FRACTION() function returns the fraction closest to num_expr whose denominator is no larger than max_denominator — the way to turn a measured decimal back into a simple ratio. The result is an exact fraction (the RATIONAL mode); FRACTION$() shows it.

Arguments:
num_expr (required): The number to approximate.
max_denominator (required): The largest denominator allowed, a whole number from 1 to 1,000,000.

Example:
print fraction$(fraction(3.14159265358979, 7))
Output: 22/7
print fraction$(fraction(3.14159265358979, 1000))
Output: 355/113

Description:
The GCD() function returns the largest whole number that divides both arguments. The arguments are whole numbers of any size the REAL type holds exactly (a 54-digit integer is fine); their signs are ignored and the result is never negative. gcd(0, b) is |b| and gcd(0, 0) is 0. Like every math function, it maps over arrays (gcd(v, 6), or two arrays element by element), and reduce(v, gcd()) gives the gcd of a whole array. A fraction as an argument raises the catchable NUM_OUTOFRANGE naming it.

Arguments:
num_expr1, num_expr2 (required): The two whole numbers.

Example:
print gcd(12, 18)
Output: 6
print gcd(-12, 18)
Output: 6
print reduce(v, gcd()) (v = 12, 18, 30)
Output: 6

See also LCM(), and the whole-number equations of diophantine() on the Array Math page (Array Math Functions, Index Lists & Slices, Solve(), Sort(), and More).

Description:
The GEODISTANCE() function calculates the straight-line distance (as the crow flies) in miles between two geographic points specified by their latitude and longitude coordinates. The function takes two string expressions, str_expr1 and str_expr2, which contain the comma-separated latitude and longitude coordinates of the two points.

Details:
The calculated distance is rounded to three decimal points. If invalid or blank coordinates are provided, the function returns a default value of 99999 miles instead of throwing an exception.

Note: The distance is calculated using Vincenty Solutions of Geodesics on an Ellipsoid, which provides high accuracy for calculating distances on the Earth's surface.

Arguments:
str_expr1 (required): The first point's latitude and longitude, comma-separated.
str_expr2 (required): The second point's latitude and longitude, comma-separated.

Example 1: Calculating the distance between two points
here$ = '37.423021,-122.083739'
there$ = '42.730287,-73.692511'
miles = geodistance(here$, there$)
print 'Distance is: '; miles; ' miles'
Output: Distance is: 2555.453 miles

Description:
The GETSYMBOL$() function retrieves the value of script variables and symbols in Sheerpower. These can include results from HTML form submissions, CGI environment variables, Sheerpower symbols, DNS symbols, operating system symbols, or any custom-defined symbols.

Details:
The function has an optional boolean parameter that controls whether leading and trailing spaces are trimmed from the returned value. By default, this parameter is set to TRUE, which trims the spaces. If set to FALSE, the spaces are preserved.

Arguments:
str_expr1 (required): The name of the symbol to retrieve.
boolean (optional): Controls trimming of leading and trailing spaces. Defaults to TRUE.

Example 1: Sheerpower Symbol with Trimming Option
set system, symbol 'test': value ' hi there'
print '<'; getsymbol$('sp:test'); '>'
print '<'; getsymbol$('sp:test', false); '>'
print '<'; getsymbol$('sp:test', true); '>'
Output:
<hi there>
< hi there>
<hi there>

Example 2: HTML Form Submission
// Print the contents of the symbol "city" from an HTML form submit.
print getsymbol$('city')

Example 3: CGI Environment Symbol
// Print the contents of the environment symbol REMOTE_ADDR (The IP address of the client)
print getsymbol$('env:REMOTE_ADDR')


Note: Sheerpower also provides the set querystring expr$ statement, which allows getsymbol$() to parse any arbitrary query string. This is handy for testing code that relies on getsymbol$().
q$='?action=run&format=myformat&filter1=coach(id)=78768' set querystring q$ print getsymbol$('filter1') // outputs coach(id)=78768

(Show/Hide CGI Environment Variables)

Example 4: Operating System Symbol
// Print the contents of the operating system symbol PATH
print getsymbol$('os:PATH')
// Print the TEMP directory path
print getsymbol$('os:TEMP')
Output:
C:\PROGRA~1\Java\JRE16~2.0_0\bin;C:\PROGRA~1\Java\JRE16~2.0_0\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\PROGRA~1\ABSOLU~1;C:\Program Files\QuickTime\QTSystem\;C:\Program Files\IDM Computer Solutions\UltraEdit\;C:\Program Files\IDM Computer Solutions\UltraCompare;.
C:\DOCUME~1\User\LOCALS~1\Temp

Supported Symbol Prefixes:

Symbol PrefixDescription
env:CGI environment variables
os:Operating system symbols. If the symbol begins with a \ then it is a registry symbol.
sp:Sheerpower symbols
dns:An IP address or domain name

Description:
The GETWORD$() function extracts the word at position num_expr in str_expr1. Words are delimited by spaces and punctuation, or a custom separator defined by str_expr2.

Arguments:
str_expr1 (required): The string containing the words.
num_expr (optional): The index of the word to extract.
str_expr2 (optional): The custom separator. Default is spaces and punctuation.

Example:
print getword$('123rd Baker Street Apt 200', 2)
Output: 123rd

Description:
The HASH$() function converts the plain text in str_expr1 into a hashed eight-byte string value. This function is useful for creating one-way hashed passwords. To further enhance the uniqueness of the hashed value, you can optionally provide a second text string str_expr2 (known as a "salt") and an integer int_expr.

Details:

  • str_expr1 (required): The plain text to be hashed.
  • str_expr2 (optional): Additional text used to "salt" the hash, enhancing uniqueness.
  • int_expr (optional): A salt integer, which further ensures the uniqueness of the hash.
  • 3 (optional): Specifies the use of "Prime Hashing," which produces a 16-digit hex string suitable for use as a table key.
The PHASH$() function, which uses a different and faster hashing method, is recommended over HASH$(). For more information, refer to Section 6.4.33, PHASH$(str_expr [, int_expr]).

Example 1: Basic Hashing
password$ = hash$('TRUTH')
input 'Password': pwd$
if hash$(pwd$) = password$ then
  print 'That was the correct password.'
else
  print 'That was not the correct password.'
end if
Output:
password? MONEY
That was not the correct password.

Example 2: Hashing with Salt
password$ = hash$('TRUTH', 'someText', 1456)
print password$
Output:
MfatL

Example 3: Prime Hashing with No Salt Integer
The optional 3 value specifies "Prime Hashing," which returns a 16-digit hex string that is very useful as a table key. If you use Prime Hashing without a salt integer, you must specify a salt of 0.
password$ = hash$('TRUTH', 'someText', 0, 3)
print password$
Output:
C8F0BE24C5880368

Description:
The HTMLDECODE$() function decodes an HTML encoded string into its corresponding characters.

Arguments:
str_expr (required): The HTML encoded string.

Example:
print htmldecode$('<html>')
Output:

Description:
The HTMLENCODE$() function encodes a string for safe use in HTML, replacing special characters with their HTML equivalents.

Arguments:
str_expr (required): The string to encode.

Example:
print htmlencode$('This is an <html> tag')
Output: This is an <html> tag

Description:
JOIN() appends up to 15 strings onto the first argument, modifying it in place: afterwards the first argument holds its original content followed by the other arguments in order.

JOIN() predates the string optimizations described at the top of this page. It still works exactly as before and appears in much existing code, but it is no longer faster than + — a plain + chain is now built in a single allocation, and s$ = s$ + piece$ grows in place, so + is the recommended way to build strings. Keep JOIN() in mind when its return value is useful or when reading older programs.

Arguments:
str_expr1 (required): The target string that receives the result.
str_expr2 to str_expr16 (optional): Strings to append in the order given.

Return Value:
Returns the length of the resulting string. This value is rarely needed; for clarity, use the throwaway variable _ when the length can be ignored.

Example:
a$ = "Well, "
b$ = "fred"
z = join(a$, "hi ", "there ", b$)
print a$
Output: Well, hi there fred

History:
JOIN() was introduced when repeated + concatenation created an intermediate string at every step; building directly into the target avoided that. Since 2026 the compiler folds literal parts at compile time, a runtime + chain is gathered in one allocation, and a loop's s$ = s$ + piece$ grows the string in place — the very work JOIN() was created to avoid. Measured: the same million-iteration build now runs faster with + than with JOIN().

Takeaway:
Write a$ = a$ + "hi " + b$. JOIN() remains fully supported for existing code and for the occasional case where the resulting length is wanted as a value.

Description:
The JOIN$() function writes every element of an array, in storage order, as one string with delim$ between the elements (default ","; an empty delim$ concatenates). Strings are written verbatim and numbers as str$() writes them. The array may be a name or an array expression (join$(ucase$(names$), "-")). An empty array gives "". _integer is set to the element count. It is the inverse of SPLIT(), and is not the older JOIN(), which concatenates its arguments into a target.

Arguments:
array (required): the array (string or numeric) to write out.
delim$ (optional): the text placed between elements. Defaults to ",".

Example:
dim v(*)
fill v with 1, 2.5, 30
print join$(v, " | ")
Output: 1 | 2.5 | 30

Description:
The LCASE$() function converts all letters in str_expr to lowercase.

Arguments:
str_expr (required): The string to convert to lowercase.

Example:
print lcase$('IT HAS BEEN A WONDERFUL DAY!')
Output: it has been a wonderful day!

Description:
The LEFT$() function returns the leftmost characters from str_expr, up to the position specified by int_expr.

Arguments:
str_expr (required): The string to extract from.
int_expr (required): The number of characters to extract from the left.

Example:
print left$('Hello there!', 3)
Output: Hel

A negative number truncates the result:
a$='abcdefghij'
print left$(a$,-3)
Output: abcdefg

Description:
The LCM() function returns the smallest positive whole number that both arguments divide: |a| / gcd(a, b) * |b|, computed exactly. It is 0 when either argument is 0, never negative, and a result past 54 digits comes back as a scientific-notation REAL. It maps over arrays and folds with reduce(v, lcm()), like GCD(). A fraction as an argument raises the catchable NUM_OUTOFRANGE naming it.

Arguments:
num_expr1, num_expr2 (required): The two whole numbers.

Example:
print lcm(12, 18)
Output: 36
print reduce(w, lcm()) (w = 8, 12, 25, 10)
Output: 600

See also GCD().

Description:
The LEN() function returns the length of str_expr as an integer.

Arguments:
str_expr (required): The string whose length is to be calculated.

Example:
print len('These are the built-in functions of Sheerpower.')
Output: 47

Description:
The LPAD$() function pads text_str on the left with the specified character to reach the specified size. The default pad character is a space.

Arguments:
text_str (required): The string to pad.
size (required): The desired size of the final string.
pad_str (optional): The character to use for padding. Default is a space.

Example:
print lpad$('123', 6, '0')
Output: 000123

Description:
The LTRIM$() function removes all leading spaces, control characters, and DEL from str_expr.

Arguments:
str_expr (required): The string to trim.

Example:
print ltrim$(' This function removes leading spaces, control characters, and DEL.')
Output: This function removes leading spaces, control characters, and DEL.

Description:
The MATCHWORD() function returns the character position of the word or phrase specified in str_expr2 within the string str_expr1. The function performs a case-insensitive search and works with both single words and phrases.

Details:

  • str_expr1 (required): The string in which to search for the word or phrase.
  • str_expr2 (required): The word or phrase to find within str_expr1.
  • num_expr (optional): The starting position for the text scan. The default is 1.
If the word or phrase is found, the function returns the character position within the string. If not found, it returns 0. After calling MATCHWORD(), the special variable _integer contains the word index number, indicating which word in the list was matched.

Example: Searching for a Word
print matchword('list of words or 11111 numbers', 'Words')
print _integer
Output:
14
3
Explanation: The word "Words" starts at character position 14 in the string, and it is the 3rd word in the list.

Description:
The MID$() function returns a substring from str_expr, starting at int_expr1 for a length of int_expr2 characters. If int_expr2 is omitted, the substring from int_expr1 to the end of the string is returned.

Arguments:
str_expr (required): The string to extract from.
int_expr1 (required): The starting position.
int_expr2 (optional): The length of the substring.

Example:
print mid$('beginmiddleend', 6, 6)
Output: middle


Related Statement: VIEW a Given Position and Length

The VIEW statement creates a live, dynamic slice of a string variable. Unlike MID$(), which returns a copy, a VIEW does not duplicate data — it binds the view variable directly to the source string.

A view automatically tracks the current value of the source variable. It updates instantly when characters change, or when the entire source variable is reassigned to a new string.

Syntax

VIEW view_var$ INTO source_var$ position numeric_expr1, length numeric_expr2

All four parameters are required:

  • view_var$ — the view variable
  • source_var$ — the source string
  • position — starting position (1-based, like MID$)
  • length — number of characters in the view
Note:
  • A view is read-only except for operations that overlay its data (such as LSET or OVERLAY()). Overlaying a view modifies the source string.
  • If the start position is beyond the end of the source, the view becomes an empty string.
  • If the view length extends past the end of the source, it is automatically truncated to fit.

Example

phone$ = "8085551212" // Create a view into the first 3 characters VIEW area$ INTO phone$: position 1, length 3 print area$ // Output: 808 // Modify the source string phone$ = "7022229999" // area$ updates automatically print area$ // Output: 702 // Overwriting a view updates the source lset area$ = "abc" print phone$ // Output: abc2229999 phone$ = "" print area$ // Output: (empty string), since phone$ now has zero length.

Multiple Views Inside a CLUSTER

You can also store multiple views inside a CLUSTER, turning a single string into a lightweight, structured record that automatically tracks the source variable. Note: A CLUSTER is a named collection of variables.

cluster parts: area$, exch$ view parts->area$ into phone$ position 1, length 3 view parts->exch$ into phone$ position 5, length 3 phone$ = "702-997-1212" print cluster parts // Outputs: 702, 997 phone$ = "213-555-1212" print cluster parts // Outputs: 213, 555

Key Differences Between MID$() and VIEW

Feature MID$() VIEW
Mechanism Creates a new string (copy) Creates a reference (pointer)
Memory Allocates new memory Points to the existing memory of the source
Behavior Static snapshot Dynamic: updates when the source variable changes
Use Case When you want a fixed value When you want to track changes

Description:
The NAMEOF$() function returns the name of a variable in uppercase. By default, it returns the base variable name, removing prefixes and trailing type marker. For example, order->total becomes TOTAL.

Think of NAMEOF$() as a way to ask: "What is this variable called?" —
This eliminates manual name mapping and keeps code and output in sync.

If the optional flag is true, the function returns the full name exactly as written, including prefixes and any trailing type markers, in uppercase.

Arguments:
variablename (required): A variable reference.
flag (optional boolean): When true, return the full name including prefixes and any trailing type marker. When omitted or false, return only the base name.
value (optional numeric): When the first argument is an enum, this specifies the enum member value. The corresponding member name is returned.

Return:
A string containing the name in uppercase.

By default, this is the base name. When flag = true, the full name is returned, including prefixes (for example REC->FIELD), array subscripts, and any trailing type marker.

When used with an enum and a value, the function returns the name of the enum member that matches the value.

enum season: spring, summer, fall, winter current = season->summer print nameof$(season, false, current) // SUMMER print "Number of fields: "; size(season,2) // 4 for idx = 1 to size(season,2) print nameof$(season, false, idx) // SPRING, SUMMER, FALL, WINTER next idx

Using NAMEOF$() with Enums

Problem: Programs often store enum values as numbers, but those numbers have no meaning when displayed in logs, reports, or user interfaces. Developers must create and maintain separate lookup tables or hardcoded strings to convert numeric values into readable names. This duplication can become inconsistent and error-prone over time.

Solution: The enhanced nameof$() function allows you to pass an enum and a value to directly retrieve the corresponding member name. This eliminates the need for manual mappings and ensures that the displayed name always matches the enum definition.

The difference becomes especially clear in logging, where numeric values provide little insight but names are immediately meaningful:

// Example: Logging enum values with meaningful names enum order_status: pending, approved, shipped, delivered status = order_status->shipped print "Order status (raw): "; status print "Order status (name): "; nameof$(order_status, false, status) // Example log output: // Order status (raw): 3 // Order status (name): SHIPPED

Efficiency: By deriving names directly from the enum, you remove duplicated logic, reduce maintenance effort, and ensure automatic consistency across logs, user interfaces, and data exports. Adding or changing enum members requires no updates elsewhere in the program.

Takeaway: Enums become self-describing. With nameof$(), you can display, iterate, and debug enum values using their actual names—without extra code or synchronization.

Notes:

  • Default behavior: Returns the variable name in uppercase, removing prefixes (for example xxx->) and any trailing type marker such as $, %, or ?.
  • With flag = true: Returns the full variable name in uppercase, preserving prefixes, array subscripts, and trailing type markers.
  • Enum usage: When a value is provided, returns the corresponding enum member name.

Example Simple Usage:

// Simple scalar a$ = "hi" print nameof$(a$) // Output: A print nameof$(a$, true) // Output: A$ // Numeric count = 42 print nameof$(count) // Output: COUNT print nameof$(count, true) // Output: COUNT // Custom type type real feet declare feet mysize print nameof$(mysize) // Output: MYSIZE // Structure / pointer-style prefix order->total = 99.50 print nameof$(order->total) // Output: TOTAL print nameof$(order->total, true) // Output: ORDER->TOTAL // Member that ends with "$" customer->name$ = "Misterdan" print nameof$(customer->name$) // Output: NAME print nameof$(customer->name$, true) // Output: CUSTOMER->NAME$

Description:
The ORD() function returns the ASCII value of the first character in str_expr.

Arguments:
str_expr (required): The character to find the ASCII value of.

Example:
print ord('H')
Output: 72

Description:
The ORDNAME$() function returns the character for the specified ASCII value.

Arguments:
int_expr (required): The ASCII value to convert to a character.

Example:
print ordname$(69)
Output: E

Description:
The PARSE$() function splits a string into tokens, returning each token separated by a space. Letters are uppercased except within quotes, and tail comments are ignored.

Arguments:
str_expr (required): The string to parse.

Example:
print parse$('company$ = 123abc$ + "and sons" !rnn')
Output: COMPANY$ = 123ABC$ + "and sons"

A colon written directly after a name stays part of that token, as the compiler reads it: parse$('xyz: print 1') is XYZ: PRINT 1 (three tokens), so a label survives a parse and re-read, while xyz : print 1 keeps the spaced colon separate.

Description:
The PHASH$() function creates a salted hash of str_expr using an optional int_expr for additional uniqueness. The result is a 24-character string that is URL-safe.

Arguments:
str_expr (required): The string to hash.
int_expr (optional): An integer to further randomize the hash.

Example:
print phash$('TRUTH', 23993)
Output: fbOdJCu87od9s50kK7zuh32W

Description:
The PIECES() function returns the number of elements in str_expr1, separated by str_expr2 (default is CR/LF). The PIECE$() function returns a specific piece of str_expr1 as specified by num_expr.

Arguments:
str_expr1 (required): The string to extract from.
str_expr2 (optional): The separator between elements. Default is CR/LF.
num_expr (required for PIECE$): The index of the piece to return.

Example:
print pieces('line1\r\nline2\r\nline3', '\r\n')
Output: 3
print piece$('line1\r\nline2\r\nline3', 2)
Output: line2

Description:
The PRETTY$() function converts text so that control characters are displayed with their names or hexadecimal values, making the text displayable on any terminal.

Arguments:
str_expr (required): The text to convert.

Example:
print pretty$('Hello' + chr$(5) + chr$(161) + chr$(7))
Output: Hello{^E}{A1}{bel}

Description:
The QUOTE$() function encloses str_expr in double quotes. If the string is already quoted, QUOTE$() leaves it as is, but converts single quotes to double quotes.

Arguments:
str_expr (required): The string to quote.

Example:
print quote$('The little boy cried "wolf!"')
Output: "The little boy cried ""wolf!"""

Description:
The REPEAT$() function repeats str_expr int_expr times.

Arguments:
str_expr (required): The string to repeat.
int_expr (required): The number of times to repeat the string.

Example:
print repeat$('Hi!', 9)
Output: Hi!Hi!Hi!Hi!Hi!Hi!Hi!Hi!Hi!

Description:
The REPLACE$() function searches for patterns in str_expr1 and replaces them with the output from str_expr2. Optional separators str_sep1 and str_sep2 can be specified.

Arguments:
str_expr1 (required): The string containing the patterns to replace.
str_expr2 (required): The string containing the replacement patterns.
str_sep1 (optional): Separator for replacement items. Default is a comma.
str_sep2 (optional): Separator between input and output text in items. Default is =.

Example:
print replace$('01-Mar-1989', 'Mar=Jun')
Output: 01-Jun-1989


Note: The default pair separator is a comma. When any replacement value contains a comma, switch the separator to a character that does not appear in your data — otherwise the comma inside the value is read as the start of a new pair.

t$ = "Total: [[total]] on [[date]]" print replace$(t$, "[[total]]=$1,234.56|[[date]]=June 25, 2026", '|') // output: Total: $1,234.56 on June 25, 2026

Description:
For a detailed description, see REGEX String Functions.

Arguments:
text_str (required): The text to operate on.

expr_str: The regular expression to use.

new_str: The new text to use.

Example:
print regexreplace$('The rain in Spain', 'rain', 'snow')
Output: The snow in Spain

Description:
The RIGHT$() function returns the rightmost characters from str_expr, up to the position specified by int_expr.

Arguments:
str_expr (required): The string to extract from.
int_expr (required): The number of characters to extract from the right.

Example:
print right$('Daniel', 2)
Output: el

Description:
The RPAD$() function pads text_str on the right with the specified character to reach the specified size. The default pad character is a space.

Arguments:
text_str (required): The string to pad.
size (required): The desired size of the final string.
pad_str (optional): The character to use for padding. Default is a space.

Example:
print rpad$('123', 6, '0')
Output: 123000

Description:
The RTFENCODE$() function encodes text for use in RTF files, ensuring that the content does not interfere with existing RTF code.

Arguments:
str_expr (required): The text to encode.

Example:
print rtfencode$('{\\rtf1\\ansi\\deff0 {\\fonttbl {\\f0 Courier;}}')
Output: \'7B\'5Crtf1\'5Cansi\'5Cdeff0 \'7B\'5Cfonttbl \'7B\'5Cf0 Courier;\'7D\'7D

Description:
The RTFDECODE$() function decodes text that has been encoded for use in RTF files.

Arguments:
str_expr (required): The RTF encoded string to decode.

Example:
print rtfdecode$("\'7B\'5Crtf1\'5Cansi\'5Cdeff0 \'7B\'5Cfonttbl \'7B\'5Cf0 Courier;\'7D\'7D")
Output: {\rtf1\ansi\deff0 {\fonttbl {\f0 Courier;}}}

Description:
The RTRIM$() function removes all trailing white space from str_expr.

Arguments:
str_expr (required): The string to trim.

Example:
let a$ = ' HELLO '
print rtrim$(a$)
Output: HELLO

Description:
The SEG$() function extracts a substring from str_expr using int_expr1 as the starting position and int_expr2 as the ending position.

Arguments:
str_expr (required): The string to extract from.
int_expr1 (required): The starting position.
int_expr2 (required): The ending position.

Example:
print seg$('abcdefghijklmnop', 3, 8)
Output: cdefgh

Description:
The SHA256$() function returns a 64-character lowercase hexadecimal digest of str_expr. With one argument it computes the standard SHA-256 hash (FIPS 180-4) — a fingerprint of the data: any change to the input, however small, produces a completely different digest. With the optional key_str it computes HMAC-SHA256 (RFC 2104) — a keyed signature that can only be produced or verified by someone who knows the key. Both the data and the key may contain any bytes.

Arguments:
str_expr (required): The data to hash or sign.
key_str (optional): The secret key. When present, the result is an HMAC-SHA256 signature instead of a plain hash. An empty key is a valid zero-length HMAC key, which is not the same as the plain hash. Keys longer than 64 bytes are handled per the HMAC standard (hashed first).

When to use which:
Use the plain hash to fingerprint data — detect that a file, record, or document changed. Use the keyed form to authenticate data — prove a message came from someone holding the secret, which is how payment providers such as Stripe, and services like GitHub and Slack, sign their webhook notifications. (It is not a password hasher — password storage needs a deliberately slow algorithm.)

Example 1: A simple hash
print sha256$('abc')
Output: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

Example 2: Any change changes everything — the same sentence with and without its final period:
print sha256$('The quick brown fox jumps over the lazy dog')
Output: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
print sha256$('The quick brown fox jumps over the lazy dog.')
Output: ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c

Example 3: Fingerprinting a document
contract$ = 'Deliver 100 widgets by Friday for $4,500'
print sha256$(contract$)
Output: 69c56e1545228198b7193fca05d9682b36f787a5cc709693b1a5b796952032ab
Store the digest; recompute it later — if the two match, the document is byte-for-byte unchanged.

Example 4: A keyed signature (HMAC-SHA256)
print sha256$('what do ya want for nothing?', 'Jefe')
Output: 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
(This is official RFC 4231 test case 2 — Sheerpower matches the standard to the digit.)

Example 5: Signing and verifying a message
message$ = 'amount=4500&payee=ACME'
signature$ = sha256$(message$, 'our-shared-secret')
print signature$
Output: ada9ae617eebaa3dfd61a2a03915173958654f24a786a2ac7c4eb1213f0635f7

The receiver, holding the same secret, recomputes and compares:
if sha256$(message$, 'our-shared-secret') = signature$ then
  print 'verified'
end if
Output: verified

A tampered message (amount=9999) produces a different signature, so the comparison fails — the forgery is detected without the secret ever traveling with the message.

Webhook verification pattern: a provider sends a timestamp t$, the raw body, and a signature; you verify with the shared webhook secret:
if sha256$(t$ + '.' + body$, webhook_secret$) = their_sig$ then
This one line is exactly how Stripe webhook notifications are authenticated.

Description:
The SORT$() function sorts the elements in str_expr1 based on their ASCII values. str_expr2 can be used to specify the separator between elements.

Arguments:
str_expr1 (required): The string containing the elements to sort.
str_expr2 (optional): The separator between elements. Default is a comma.

Example:
print sort$('code area is', ' ')
Output: area code is

Description:
The SPACE$() function returns a string consisting of num_expr spaces.

Arguments:
num_expr (required): The number of spaces to return.

Example:
print space$(10)
Output: (10 spaces)

Description:
The SPLIT() function returns a string ARRAY holding the pieces of str_expr between occurrences of delim$ (default ","; any length). The pieces are verbatim — nothing is trimmed, so trim$(split(line$)) is the cleaned form. An empty string gives an empty array (size() 0); leading, trailing or adjacent delimiters give empty pieces; an EMPTY delim$ raises the catchable exception BADFORMAT. The target must be an expandable string array (dim words$(*)) — assigning to a plain string raises ARRAYRESULT. _integer is set to the piece count. Works wherever an array expression works: ucase$(split(s$)), size(split(s$)), print split(s$). See Array Math Functions, Index Lists & Slices, Solve(), Sort(), and More section 14; ELEMENT$() returns one piece, SPLIT() all of them.

Arguments:
str_expr (required): the text to split.
delim$ (optional): the delimiter, one or more characters. Defaults to ",".

Example:
dim words$(*)
words$ = split("apple::pear::fig", "::")
print size(words$); " "; words$(2)
Output: 3 pear

Description:
The STR$() function converts num_expr to a string without adding any extra spaces.

Arguments:
num_expr (required): The number to convert.

Example:
print str$(22)
Output: 22

Description:
The TAB() function moves the cursor to the column specified by int_expr. It is often used with the PRINT statement for formatting output.

Arguments:
int_expr (required): The column number to move the cursor to.

Example:
print tab(20); 'Hello there!'
Output: (spaces up to column 20) Hello there!

Description:
The TRIM$() function removes both leading and trailing spaces, control characters, and DEL from str_expr.

Arguments:
str_expr (required): The string to trim.

Example:
let a$ = ' HELLO '
print trim$(a$)
Output: HELLO

Description:
The TYPEOF$() function is used to determine the primitive data type and any custom type of a variable. This can be particularly useful in generic routines where developers may want to use specific logic based on the data type of the variables passed in.

Arguments:
variable (required): The variable whose type is being queried.

Return:
The function returns a string with the format "Name:VariableName, Dtype:DataType, Ctype:CustomType" if a custom type is defined, or just "Name:VariableName, Dtype:DataType" if no custom type is defined. It will also indicate with "*Nodump*" is the variable is to be excluded from crash dumps, etc.

Example Usage:

a$ = 'hi' print typeof$(a$) // Output: Name:A$, Dtype:String age = 56 print typeof$(age) // Output: Name:AGE, Dtype:Real type real feet declare feet mysize mysize = 6 print typeof$(mysize) // Output: Name:MYSIZE, Dtype:Real, Ctype:FEET type nodump string secret declare secret password password = 'xxxyyy' print typeof$(password) // Output: Name:PASSWORD, Dtype:String, Ctype:SECRET, *Nodump*

Example Usage in a Routine:

This example shows how the TYPEOF$() function can be used in a temperature conversion routine that always outputs temperatures in Fahrenheit, even if the input is in Celsius.

routine convert_to_fahrenheit with temperature, returning result if pos(typeof$(temperature), "Ctype:CELSIUS") > 0 then result = (temperature * 9 / 5) + 32 else result = temperature // Assume input is already in Fahrenheit end if end routine type real celsius declare celsius temperature temperature = 100 convert_to_fahrenheit with temperature, returning result print 'Result in fahrenheit: '; result

Description:
The UCASE$() function converts all letters in str_expr to uppercase.

Arguments:
str_expr (required): The string to convert to uppercase.

Example:
print ucase$('are you enjoying this manual so far?')
Output: ARE YOU ENJOYING THIS MANUAL SO FAR?

Description:
The UNQUOTE$() function removes one set of quotes from str_expr. If the string is not quoted, UNQUOTE$() leaves it unchanged.

Arguments:
str_expr (required): The string to unquote.

Example:
print unquote$('I will not take these ''things'' for granted.')
Output: I will not take these 'things' for granted.

Description:
The URLENCODE$() function converts a string into a format that can be safely used in a URL. Spaces are converted to + signs, and special characters are encoded as hexadecimal values.

Arguments:
str_expr (required): The string to encode.

Example:
print urlencode$('Dogs & cats')
Output: Dogs+%26+cats

Description:
The URLDECODE$() function decodes a URL-encoded string back to its original text, converting + signs back to spaces and hexadecimal values to their corresponding characters.

Arguments:
str_expr (required): The URL-encoded string to decode.

Example:
print urldecode$('Dogs+%26+cats')
Output: Dogs & cats

Description:
The UUID$() function generates a "universally unique identifier" (UUID) that can be used as a unique key for a table. It ensures that key values are sparse, making them difficult to guess or enter accidentally.

Details:
The function can be called with no parameters or with a single parameter that specifies the format, with the default format being 0. Additionally, a third parameter can be used to specify the total desired return length, in which case multiple UUIDs are generated and concatenated until the specified length is achieved.

Formats:

  • 0: 32 hex digits made from the 128-bit UUID in memory byte order. This format is very fast (over 3 million/sec) and is the default if no parameter is given.
  • 1: 32 hex digits in RFC-specified order, allowing meaning to be attached to the hex digits (about 900,000/sec).
  • 2: 32 hex digits grouped with four dashes (about 900,000/sec), resulting in 36 characters in total.
  • 3: Similar to format 2 but with additional braces at the front and back. This is the standard display format for a UUID, resulting in 38 characters in total.

Example:
print uuid$
print uuid$(0) // base64-encoded UUID (default), is the same as UUID$
print uuid$(1) // UUID in hex digits
print uuid$(2) // UUID in hex with dashes
print uuid$(3) // UUID in hex with dashes, enclosed with braces
Sample results:
_Tgn05ms3UeHyarCf8zSlg
Rcy4J8f3306y05huwMOtSA
B6C33FB8253D46038E07C00A8002D9F7
C126D0DF-959D-4954-B581-F505AB9DD541
{43FB8797-E2A8-42A3-8B8B-9B391C45F850}

Note: The default UUID format returns 22 bytes, achieved by converting the 128-bit standard internal UUID into a base-64 encoded string, then stripping off the trailing two "=" characters. For URL safety, "+" is changed to "-" and "/" to "_". UUIDs are also known as GUIDs (Globally Unique Identifiers). For more information on UUIDs, visit: Wikipedia on UUIDs.

Description:
The VAL() function converts num_str to a REAL value. For a more detailed description, see Strings to Reals -- Extracting Numbers From Text.

Arguments:
num_str (required): The string to convert.

Example:
print val('4.567')
Output: 4.567

Description:
The WRAP$() function returns a word-wrapped version of str_expr, with each line of text wrapped between int_expr1 and int_expr2 margins.

Arguments:
str_expr (required): The string to wrap.
int_expr1 (required): The left margin.
int_expr2 (required): The right margin.

Example:
print wrap$('This is an example of the wrap$ function.', 5, 15)
Output:
This is an
example of
the wrap$
function.

Description:
The XLATE$() function translates characters in str_expr1 using a translation table specified by str_expr2.

Arguments:
str_expr1 (required): The string to translate.
str_expr2 (required): The translation table.

Example:
a$ = charset$()
a$[66:66] = 'x'
print xlate$('DAN', a$)
Output: DxN

Description:
The xor$() function returns a string where each bit is the result of a bit-wise XOR operation between the corresponding bits of str1$ and str2$. This function is useful for performing operations like OTP (One-Time Pad) encryption.

Arguments:
str1$ (required): The first string.
str2$ (required): The second string.

Example:
a$ = 'hi there'
k$ = uuid$(0, len(a$))
e$ = xor$(a$, k$)
print xor$(e$, k$)
Output: hi there

Description:
The _GID$ special variable returns a 30-character, browser-safe identifier that combines a date stamp and a unique ID. The result is both globally unique and sortable by creation date.

Details:
The identifier has two parts:

  • Date-stamp prefix: Encodes the current date (YYYYMMDD) for chronological sorting.
  • UUID portion: A globally unique sequence using URL-safe characters, similar to UUID$().

Example:

print _gid$ 20251021_a7B9kX3mQ8zLpN5vT2
Comparison:
Unlike UUID$(), _GID$ includes a sortable date prefix for natural chronological ordering. (It does not include time-of-day.)

Use Cases:

  • Transaction logs: Date-ordered, unique entries for auditing.
  • Sessions and orders: Unique Sortable IDs with or without separate date-stamp fields.
  • File uploads and API requests: Web-safe unique IDs for filenames or request tracking.
  • Message queues: Chronological, unique message identifiers.
Note:
_GID$ creates unique, date-sortable IDs safe for use in URLs, JSON, or database tables. Its fixed 30-character length fits standard field limits.

Description:
The _ROUTINE$ special variable returns the name of the routine that contains its reference. This value is determined at runtime, allowing the executing code to be aware of its current context without requiring any hard-coded identifiers.

This capability is especially useful for logging, diagnostics, and debugging. Knowing exactly which routine is executing can significantly reduce the time required to trace issues, especially in large systems with many routines and layers of calls.

By embedding _ROUTINE$ in log messages, error reports, or audit trails, developers gain precise visibility into program flow. This is particularly valuable when analyzing production logs or investigating unexpected behavior.

Because _ROUTINE$ always reflects the actual routine name, it eliminates the need to manually maintain string labels for identification. This avoids a common class of errors where logging messages become outdated after refactoring or routine renaming. The result is more reliable and maintainable instrumentation.

In structured systems that make heavy use of reusable routines, nested calls, or shared libraries, _ROUTINE$ provides a lightweight form of introspection. A routine can identify itself dynamically, supporting logging, conditional behavior, and standardized diagnostic output.

A typical usage pattern might include incorporating _ROUTINE$ into a logging statement:

print "Entering routine: " + _ROUTINE$

This simple addition ensures that every execution path is clearly labeled, making it much easier to follow program flow during debugging sessions or when reviewing logs from production systems.

Overall, _ROUTINE$ reflects a broader design principle in Sheerpower: reduce manual bookkeeping while increasing clarity. By making execution context directly available, it helps produce systems that are easier to debug, audit, and maintain over time.


Together, these features allow Sheerpower to handle string-heavy workloads with a high-level of efficiency and predictability.
(Show/Hide Sheerpower String Handling Takeaways)

The code below contains examples of some of the major string functions.

Hide Description

    

       


      

Enter or modify the code below, and then click on RUN

Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use.