StdLib — Standard Library
Essential utility functions for Plan9Basic programs. These core functions support program flow control, type checking, type conversion, object introspection, and regional format configuration. They work across all supported platforms.
| Category | Functions | Description |
|---|---|---|
| Program Control | 3 | Pause execution, process system messages |
| Type Checking | 5 | Detect NaN, infinity, null strings, nil pointers, sign |
| Type Conversion | 3 | Convert between pointers and numbers |
| Object Information | 1 | Get class name of objects |
| Format Settings | 2 | Get/set regional format settings (dates, numbers, times) |
Program Control
Functions for managing program execution timing and system message processing.
| Function | Signature | Description |
|---|---|---|
pause(seconds) | pause@n | Pause execution for n whole seconds |
processmessages() | processmessages@ | Process all pending system messages |
handlemessage() | handlemessage@ | Process a single pending system message |
pause(seconds)
Pauses program execution for a specified number of whole seconds. Fractional values are truncated to the integer part. Returns 0.
println "Starting..." pause(2) ' Pause for 2 seconds println "2 seconds later..." pause(1) ' Pause for 1 second println "Done!"
pause() function only accepts whole seconds. pause(0.5) is truncated to 0 and produces no delay. For sub-second timing, use Timer controls from the GUI library.processmessages().processmessages()
Processes all pending system messages, allowing the application to remain responsive during long operations. Returns 1.
' Long operation with responsive UI for i = 1 to 1000000 ' Do some work... ' Process messages every 1000 iterations if i mod 1000 = 0 then processmessages() endif next
Use cases: keeping the UI responsive during long calculations, allowing button clicks during loops, preventing “application not responding” states.
handlemessage()
Processes a single pending system message from the queue. Returns 1. Use when you need more granular control over message processing; processmessages() is generally preferred.
' Process one message at a time for finer control handlemessage()
Type Checking
Functions for detecting invalid or special values.
| Function | Signature | Description |
|---|---|---|
isnan(n) | isnan@n | Is Not-a-Number? (1=yes, 0=no) |
isinfinite(n) | isinfinite@n | Is infinite? (1=yes, 0=no) |
isnull(s$) | isnull@$ | Is string null/empty? (1=yes, 0=no) |
isassigned(p#) | isassigned@# | Is pointer assigned? (1=assigned, 0=nil) |
sign(n) | sign@n | Sign of number: -1, 0, or 1 |
isnan(n)
Tests whether a numeric value is “Not a Number” (NaN). Returns 1 if NaN, 0 if valid.
a = 0 / 0 ' This might produce NaN b = sqr(-1) ' Square root of negative number if isnan(a) = 1 then println "a is not a number" endif ' Safe calculation with NaN check value = someCalculation() if isnan(value) = 1 then println "Calculation resulted in an invalid value" value = 0 ' Use default endif
Common NaN sources: division of 0 by 0, square root of negative numbers, logarithm of negative numbers, and other invalid mathematical operations.
isinfinite(n)
Tests whether a numeric value represents positive or negative infinity. Returns 1 if infinite, 0 if finite.
a = 1 / 0 ' Division by zero produces infinity b = -1 / 0 ' Negative infinity if isinfinite(a) = 1 then println "a is infinite" endif ' Validate calculation results result = someCalculation() if isinfinite(result) = 1 then println "Result overflow - value is infinite" endif
isnull(s$)
Tests whether a string is null (empty or contains only the null character #0). Returns 1 if null, 0 if content exists.
a$ = "" b$ = "Hello" if isnull(a$) = 1 then println "a$ is null or empty" endif if isnull(b$) = 0 then println "b$ has content: "; b$ endif
isassigned(p#)
Tests whether a pointer is assigned (not nil). Returns 1 if assigned (not nil), 0 if nil.
obj# = createSomeObject() if isassigned(obj#) = 1 then println "Object was created successfully" else println "Object creation failed (nil pointer)" endif
isassigned() returns 1 when the pointer IS valid (assigned). Think of it as “is not nil”. When the pointer is nil, it returns 0.sign(n)
Returns the sign of a number: 1 if positive, 0 if zero, -1 if negative.
println sign(42) ' Output: 1 println sign(0) ' Output: 0 println sign(-17) ' Output: -1 ' Use sign to determine direction velocity = -5 direction = sign(velocity) if direction = 1 then println "Moving forward" else if direction = -1 then println "Moving backward" else println "Stationary" endif
sgn() in NumLib.Type Conversion
Functions for converting between pointers and numeric values.
| Function | Signature | Description |
|---|---|---|
number(p#) | number@# | Pointer → numeric address |
pointer#(n) | pointer#@n | Numeric address → pointer |
pnttonum(p#) | pnttonum@# | Pointer → numeric (nil-safe, returns 0 for nil) |
number(p#)
Converts a pointer value to its numeric (integer) representation — the raw memory address.
obj# = createSomeObject() addr = number(obj#) println "Object address: "; addr
pointer#(n)
Converts a numeric value to a pointer.
' Store a pointer as a number and restore it obj# = createSomeObject() addr = number(obj#) ' Later, restore the pointer restored# = pointer#(addr)
pointer#() with extreme caution. Creating pointers from arbitrary numbers can cause crashes or undefined behavior if the address is invalid.pnttonum(p#)
Converts a pointer to a numeric value with nil checking. Returns 0 if the pointer is nil — safer than number().
' Safe nil check using pnttonum obj# = createSomeObject() addr = pnttonum(obj#) if addr = 0 then println "Pointer is nil" else println "Pointer address: "; addr endif
pnttonum() is the recommended way to compare pointers to numbers. Direct pointer comparison in conditionals is not supported — always convert first.Object Information
| Function | Signature | Description |
|---|---|---|
classname$(p#) | classname$@# | Get the class name of an object |
Returns the Delphi class name of the object referenced by a pointer. Useful for runtime type checking and debugging.
obj# = json_object#() println "Type: "; classname$(obj#) ' Output: "TJSONObject" ' Use for runtime type checking if classname$(obj#) = "TStringList" then println "It's a string list" endif
Format Settings
Plan9Basic uses the system’s regional settings for formatting dates, times, and numbers. These functions let you customize those settings at runtime.
| Function | Signature | Description |
|---|---|---|
formatsettings(name$, value$) | formatsettings@$$ | Set a format setting (returns 1=ok, 0=unknown) |
formatsettings$(name$) | formatsettings$@$ | Get the current value of a format setting |
Available Settings
| Setting Name | Type | Description | Example Values |
|---|---|---|---|
dateseparator | Char | Character separating date parts | / - . |
timeseparator | Char | Character separating time parts | : . |
decimalseparator | Char | Decimal point character | . , |
shortdateformat | String | Short date format pattern | MM/dd/yyyy |
longdateformat | String | Long date format pattern | MMMM d, yyyy |
shorttimeformat | String | Short time format pattern | HH:mm |
longtimeformat | String | Long time format pattern | HH:mm:ss |
timeamstring | String | AM indicator | AM |
timepmstring | String | PM indicator | PM |
' Get current settings println "Date separator: "; formatsettings$("dateseparator") println "Decimal separator: "; formatsettings$("decimalseparator") println "Short date format: "; formatsettings$("shortdateformat") ' Change to European format formatsettings("dateseparator", ".") formatsettings("decimalseparator", ",") formatsettings("shortdateformat", "dd.MM.yyyy") println "New date separator: "; formatsettings$("dateseparator")
Complete Examples
Safe Calculation with Validation
' Perform calculations with proper error checking function safeDivide(a, b) local result if b = 0 then println "Warning: Division by zero" return 0 endif result = a / b if isnan(result) = 1 then println "Warning: Result is NaN" return 0 endif if isinfinite(result) = 1 then println "Warning: Result is infinite" return 0 endif return result endfunction function safeSqrt(n) local result if n < 0 then println "Warning: Cannot take square root of negative number" return 0 endif result = sqr(n) if isnan(result) = 1 then return 0 endif return result endfunction println "=== Safe Calculation Demo ===" println "" println "10 / 2 = "; safeDivide(10, 2) println "10 / 0 = "; safeDivide(10, 0) println "sqrt(16) = "; safeSqrt(16) println "sqrt(-4) = "; safeSqrt(-4)
Progress Indicator with Responsive UI
' Simulate a long operation with progress updates println "=== Processing with Progress ===" println "" total = 100 for i = 1 to total ' Simulate work processmessages() ' Update progress every 10% if i mod 10 = 0 then println "Progress: "; i; "%" pause(1) endif next println "" println "Processing complete!"
Responsive Countdown Timer
' Simple countdown timer function countdown(seconds) local i println "Countdown starting from "; seconds; " seconds..." println "" for i = seconds to 1 step -1 println i; "..." pause(1) processmessages() next println "" println "Time's up!" return 0 endfunction countdown(5)
Regional Format Configuration
' Configure and display format settings println "=== Format Settings Demo ===" println "" ' Display current settings println "Current Settings:" println " Date separator: "; formatsettings$("dateseparator") println " Time separator: "; formatsettings$("timeseparator") println " Decimal separator: "; formatsettings$("decimalseparator") println " Short date format: "; formatsettings$("shortdateformat") println " AM string: "; formatsettings$("timeamstring") println " PM string: "; formatsettings$("timepmstring") println "" ' Switch to European format println "Switching to European format..." formatsettings("dateseparator", ".") formatsettings("shortdateformat", "dd.MM.yyyy") formatsettings("decimalseparator", ",") println "" println "New Settings:" println " Date separator: "; formatsettings$("dateseparator") println " Short date format: "; formatsettings$("shortdateformat") println " Decimal separator: "; formatsettings$("decimalseparator")
Value Validation Utility
' Comprehensive value validation function validateNumber(value) local valid valid = 1 if isnan(value) = 1 then println " - Value is NaN" valid = 0 endif if isinfinite(value) = 1 then println " - Value is infinite" valid = 0 endif return valid endfunction function validateString(value$) local valid valid = 1 if isnull(value$) = 1 then println " - String is null or empty" valid = 0 endif return valid endfunction function validatePointer(value#) local valid valid = 1 if isassigned(value#) = 0 then println " - Pointer is nil" valid = 0 endif return valid endfunction println "=== Value Validation Demo ===" println "" println "Validating 42:" validateNumber(42) println "Validating 0/0:" validateNumber(0/0) println "" println "Validating 'Hello':" validateString("Hello") println "Validating '':" validateString("")
Number Sign Analysis
' Analyze the sign of numbers println "=== Number Sign Analysis ===" println "" for i = -3 to 3 s = sign(i) print i; " is "; if s = 1 then println "positive" else if s = -1 then println "negative" else println "zero" endif next
Best Practices
Pause Limitations
| Call | Result |
|---|---|
pause(1) | Pauses 1 second ✓ |
pause(2) | Pauses 2 seconds ✓ |
pause(0.5) | Truncated to 0 — no pause ✗ |
pause(1.9) | Truncated to 1 second |
For sub-second timing or animations, use Timer controls from the GUI library instead.
Pause and Responsiveness
When using pause() for extended periods, break it into smaller chunks:
' Instead of: pause(10) ' UI frozen for 10 seconds ' Use: for i = 1 to 10 pause(1) processmessages() next
Checking for Invalid Values
Always validate calculation results that might produce special values:
result = someCalculation() if isnan(result) = 1 or isinfinite(result) = 1 then ' Handle error result = 0 endif
Pointer Safety
Always check for nil before using a pointer:
obj# = getObject() if isassigned(obj#) = 1 then ' Safe to use obj# println classname$(obj#) else println "Object is nil" endif
Quick Reference
| Function | Signature | Description |
|---|---|---|
pause(seconds) | pause@n | Pause execution (whole seconds only) |
processmessages() | processmessages@ | Process all pending system messages |
handlemessage() | handlemessage@ | Process single system message |
isnan(n) | isnan@n | Is Not-a-Number? (1=yes, 0=no) |
isinfinite(n) | isinfinite@n | Is infinite? (1=yes, 0=no) |
isnull(s$) | isnull@$ | Is string null/empty? (1=yes, 0=no) |
isassigned(p#) | isassigned@# | Is pointer assigned? (1=yes, 0=nil) |
sign(n) | sign@n | Sign: -1, 0, or 1 |
number(p#) | number@# | Pointer → numeric address |
pointer#(n) | pointer#@n | Numeric address → pointer |
pnttonum(p#) | pnttonum@# | Pointer → numeric (nil-safe) |
classname$(p#) | classname$@# | Class name of object |
formatsettings(name$, val$) | formatsettings@$$ | Set format setting (1/0) |
formatsettings$(name$) | formatsettings$@$ | Get format setting |
14 functions total across 5 categories.