Built-in Functions

Complete reference for all built-in functions.

Output Functions

FunctionDescription
say($value)Print value with newline
print($value)Print value without newline
warn($msg)Print warning to stderr
die($msg)Print error and exit

String Functions

FunctionDescription
length($str)Length in Unicode codepoints (use core::byte_length for raw bytes)
strlen($str)Alias for length
substr($str, $start, $len)Extract substring (offsets are codepoint positions, UTF-8 safe)
index($str, $substr)Find first occurrence (codepoint position), -1 if not found
rindex($str, $substr)Find last occurrence (codepoint position)
uc($str)Convert to uppercase
lc($str)Convert to lowercase
ucfirst($str)Uppercase first character
lcfirst($str)Lowercase first character
trim($str)Remove leading/trailing whitespace
split($sep, $str)Split string into array
join($sep, @arr)Join array into string
chr($code)Character from ASCII code
ord($char)ASCII code from character
sprintf($fmt, ...)Formatted string (like C sprintf)
stringify($val)Convert value to string

String Repetition Operator (x)

The x operator repeats a string a given number of times. It has the same precedence as *, /, and %.

my str $dashes = "-" x 40;
say($dashes);  # "----------------------------------------"

my str $ab = "ab" x 3;
say($ab);  # "ababab"

# Useful for formatting
say("=" x 60);
say("  Report Title");
say("=" x 60);

Transliteration (tr///, y///)

The tr/// operator (alias y///) performs character-by-character transliteration. Unlike s///, it does not use regex — it maps individual characters from one set to another.

SyntaxDescription
$str =~ tr/abc/xyz/;Replace a with x, b with y, c with z (modifies in place)
$str =~ y/abc/xyz/;Same as tr/// (Perl alias)
my str $new = ($str =~ tr/abc/xyz/r);Return new string instead of modifying (with /r flag)

Flags

FlagDescription
cComplement — transliterate characters NOT in the search list
dDelete — delete characters with no replacement
sSqueeze — collapse duplicate replaced characters into one
rReturn — return new string, do not modify original
my str $text = "Hello World";

# ROT13
$text =~ tr/A-Za-z/N-ZA-Mn-za-m/;
say($text);  # "Uryyb Jbeyq"

# Lowercase to uppercase
my str $upper = "hello";
$upper =~ tr/a-z/A-Z/;
say($upper);  # "HELLO"

# Delete digits
my str $nodigits = "abc123def456";
$nodigits =~ tr/0-9//d;
say($nodigits);  # "abcdef"

# Squeeze repeated spaces
my str $spaced = "hello    world";
$spaced =~ tr/ / /s;
say($spaced);  # "hello world"

# Return modified copy (original unchanged)
my str $original = "hello";
my str $copy = ($original =~ tr/a-z/A-Z/r);
say($original);  # "hello" (unchanged)
say($copy);      # "HELLO"

Examples

my str $s = "  Hello World  ";
say(strlen($s));           # 15
say(trim($s));             # "Hello World"
say(substr($s, 2, 5));    # "Hello"
say(uc($s));               # "  HELLO WORLD  "
say(index($s, "World"));  # 8

my array @parts = split(" ", trim($s));
say(join("-", @parts));   # "Hello-World"

Array Functions

FunctionDescription
len(@arr)Return array length
scalar(@arr)Return array length (alias for len)
push(@arr, $val)Add element to end
pop(@arr)Remove and return last element
shift(@arr)Remove and return first element
unshift(@arr, $val)Add element to beginning
reverse(@arr)Reverse array elements in place
sort(@arr)Return sorted array
splice(@arr, $off, $len)Remove elements, return removed
splice(@arr, $off, $len, @repl)Remove and replace with @repl, return removed

splice() in Detail

The splice() function removes elements from an array and optionally replaces them. It returns an array of the removed elements.

my array @data = (10, 20, 30, 40, 50);

# Remove 2 elements starting at index 1
my array @removed = splice(@data, 1, 2);
# @removed = (20, 30), @data = (10, 40, 50)

# Replace 1 element at index 1 with two new elements
my array @arr = ("a", "b", "c", "d");
my array @repl = ("X", "Y");
splice(@arr, 1, 1, @repl);
# @arr = ("a", "X", "Y", "c", "d")

# Insert without removing (len = 0)
my array @list = (1, 2, 5);
my array @insert = (3, 4);
splice(@list, 2, 0, @insert);
# @list = (1, 2, 3, 4, 5)

Array Memory Management

FunctionDescription
reserve(@arr, $n)Ensure capacity for at least $n elements

Pre-allocating Arrays

For performance, pre-allocate arrays when you know the approximate size:

my array @data[1000];  # Pre-allocate for 1000 elements
for (my int $i = 0; $i < 1000; $i++) {
    push(@data, $i);  # No reallocation needed
}

Array Transformations (map, grep, sort)

Strada supports Perl-style block expressions for powerful array transformations. The special variable $_ contains the current element.

ExpressionDescription
map { expr } @arrTransform each element
grep { cond } @arrFilter elements where condition is true
sort { $a <=> $b } @arrSort with custom comparison ($a, $b)
sort @arrSort alphabetically (default)

Map Examples

my array @nums = (1, 2, 3, 4, 5);

# Transform each element (double)
my array @doubled = map { $_ * 2 } @nums;
# Result: (2, 4, 6, 8, 10)

# Transform to strings
my array @strings = map { "Value: " . $_ } @nums;

Map with Fat Arrow (Creating Hashes)

The classic Perl idiom for building lookup hashes works in Strada:

my array @fruits = ("apple", "banana", "cherry");

# Create a lookup hash - the Perl way!
my hash %lookup = map { $_ => 1 } @fruits;
# %lookup is now {"apple" => 1, "banana" => 1, "cherry" => 1}

# Fast membership testing
if (exists($lookup{"apple"})) {
    say("Found apple!");
}

The fat arrow $_ => value creates a key-value pair. When assigned to a hash variable, these pairs become hash entries.

Grep Examples

my array @nums = (1, 2, 3, 4, 5, 6);

# Keep only even numbers
my array @evens = grep { $_ % 2 == 0 } @nums;
# Result: (2, 4, 6)

# Keep values greater than 3
my array @big = grep { $_ > 3 } @nums;
# Result: (4, 5, 6)

Sort Examples

my array @nums = (5, 2, 8, 1, 9);

# Sort ascending (numeric) - use spaceship operator
my array @asc = sort { $a <=> $b } @nums;
# Result: (1, 2, 5, 8, 9)

# Sort descending
my array @desc = sort { $b <=> $a } @nums;
# Result: (9, 8, 5, 2, 1)

# Default sort (alphabetical)
my array @alpha = sort @names;

Chaining Operations

my array @data = (5, 2, 8, 1, 9, 3, 7);

# Filter, transform, and sort in one pipeline
my array @result = sort { $a <=> $b } map { $_ * 10 } grep { $_ > 3 } @data;
# Result: (50, 70, 80, 90)

Hash Functions

FunctionDescription
keys(%hash)Return array of keys
values(%hash)Return array of values
exists(%hash, $key)Check if key exists (returns 1/0)
delete(%hash, $key)Remove key-value pair
each(%hash)Return next [key, value] pair; empty array when done
core::hash_default_capacity($n)Set default capacity for new hashes

each() Iterator

The each() function returns the next key-value pair from a hash as a two-element array [key, value]. When all pairs have been returned, it returns an empty array. The iterator resets when all entries have been traversed.

my hash %config = ();
$config{"host"} = "localhost";
$config{"port"} = 8080;
$config{"debug"} = 1;

# Iterate with each()
my array @pair = each(%config);
while (scalar(@pair) > 0) {
    say($pair[0] . " = " . $pair[1]);
    @pair = each(%config);
}
# Output (order may vary):
#   host = localhost
#   port = 8080
#   debug = 1

Pre-allocating Hashes

Pre-allocate hashes when you know the approximate size:

my hash %cache[500];  # Pre-allocate for ~500 entries

# Or set default for all new hashes:
core::hash_default_capacity(1000);

Hashes automatically resize for O(1) average lookup time.

Type Functions

FunctionDescription
int($val)Convert to integer
num($val)Convert to number
defined($val)Check if value is defined
ref($val)Return reference type or empty string
typeof($val)Return type as string
bless(\%h, $class)Associate hash ref with class
core::weaken($ref)Make $ref a weak reference (break circular refs)
core::isweak($ref)Returns 1 if $ref is weak, 0 otherwise

File I/O Functions

FunctionDescription
slurp($path)Read entire file as string
spew($path, $data)Write string to file
core::open($path, $mode)Open file, return filehandle (modes: "r"/"<", "w"/">", "a"/">>")
core::open(\$var, $mode)Open in-memory handle (ref-style, writeback on close)
core::open_str($content, $mode)Open in-memory handle from string
core::str_from_fh($fh)Extract string from memstream
core::readline($fh)Read line from filehandle
core::read($fd, $len)Read bytes from fd
core::fwrite($fd, $data)Write bytes to fd
core::close($fd)Close file descriptor
core::seek($fd, $pos, $whence)Seek in file
core::tell($fd)Get current position
core::eof($fd)Check if at end of file
core::flush($fd)Flush file buffer
select($fh)Set default filehandle for print/say

select() — Default Filehandle

The select() function sets the default output filehandle. After calling select($fh), all print() and say() calls without an explicit filehandle will write to $fh instead of stdout.

my scalar $fh = core::open("output.log", "w");

# Redirect print/say to the file
select($fh);
say("This goes to output.log");
print("So does this");

# Restore stdout (pass undef or no argument)
select(undef);
say("Back to stdout");

core::close($fh);

Diamond Operator <$fh>

The diamond operator reads lines from a filehandle or socket. Context determines behavior:

SyntaxContextDescription
my str $line = <$fh>ScalarRead one line (strips newline)
my array @lines = <$fh>ArrayRead ALL lines into array
@lines = <$fh>ArrayRead ALL lines (assignment)
<$sock>AnyWorks with sockets too (strips \r\n)

Filehandle I/O

Say and print work with filehandles as the first argument:

SyntaxDescription
say($fh, $text)Write text with newline to filehandle/socket
print($fh, $text)Write text without newline to filehandle/socket

In-Memory I/O

Read from and write to strings using standard file handle operations. All I/O functions work transparently with in-memory handles.

# Read from a string
my scalar $fh = core::open_str("line1\nline2\n", "r");
my str $line = <$fh>;  # "line1"

# Write to a string buffer
my scalar $wfh = core::open_str("", "w");
say($wfh, "hello");
my str $result = core::str_from_fh($wfh);  # "hello\n"

# Reference-style (variable updated on close)
my str $output = "";
my scalar $wfh2 = core::open(\$output, "w");
say($wfh2, "data");
core::close($wfh2);  # $output = "data\n"

Math Functions (math::)

FunctionDescription
math::abs($n)Absolute value
math::floor($n)Round down
math::ceil($n)Round up
math::round($n)Round to nearest
math::sqrt($n)Square root
math::pow($base, $exp)Power
math::sin($n)Sine
math::cos($n)Cosine
math::tan($n)Tangent
math::log($n)Natural logarithm
math::log10($n)Base-10 logarithm
math::exp($n)e^n
math::rand()Random number 0-1
math::srand($seed)Seed random generator

System Functions (core::)

Process Control

FunctionDescription
core::exit($code)Exit with status code
core::fork()Fork process
core::exec($cmd, @args)Execute command
core::system($cmd)Run shell command
core::wait()Wait for child process
core::waitpid($pid)Wait for specific process
core::getpid()Get process ID
core::getppid()Get parent process ID
core::kill($pid, $sig)Send signal to process

Environment

FunctionDescription
core::getenv($name)Get environment variable
core::setenv($name, $val)Set environment variable
core::getcwd()Get current directory
core::chdir($path)Change directory

File System

FunctionDescription
core::stat($path)Get file info
core::mkdir($path)Create directory
core::rmdir($path)Remove directory
core::unlink($path)Delete file
core::rename($old, $new)Rename file
core::readdir($path)List directory
core::is_dir($path)Check if directory
core::is_file($path)Check if regular file
core::realpath($path)Get absolute path
core::dirname($path)Get directory part
core::basename($path)Get filename part
core::glob($pattern)Glob pattern matching
-e $pathFile test: exists (file or directory)
-f $pathFile test: is a regular file
-d $pathFile test: is a directory

Time

FunctionDescription
core::time()Unix timestamp
core::localtime($ts)Convert to local time hash
core::gmtime($ts)Convert to GMT hash
core::sleep($secs)Sleep for seconds
core::usleep($usecs)Sleep for microseconds

Debugging

FunctionDescription
core::stack_trace()Get current call stack as string
core::caller()Returns hash with function, file, line of calling frame
core::caller($level)Same, but $level frames up (0 = immediate, 1 = grandparent)
core::full_profile_start($file)Start line-level profiling, writing output to $file
core::full_profile_stop()Stop line-level profiling and flush data to disk

Call Context (Dynamic Return Type)

FunctionDescription
core::wantarray()Returns 1 if called in array context
core::wantscalar()Returns 1 if called in scalar context (default)
core::wanthash()Returns 1 if called in hash context

Networking

FunctionDescription
core::socket_server($port)Create TCP server
core::socket_accept($fd)Accept connection
core::socket_connect($host, $port)Connect to server
core::gethostbyname($host)Resolve hostname
core::gethostbyname_all($host)Resolve hostname (all addresses)
core::gethostname()Get local hostname
core::getaddrinfo($host, $port)Advanced address resolution

SSL/TLS (ssl::)

Secure socket connections via OpenSSL. Build with: cd lib/ssl && make

FunctionDescription
ssl::connect($host, $port)Connect to TLS server
ssl::read($conn, $len)Read from TLS connection
ssl::write($conn, $data)Write to TLS connection
ssl::close($conn)Close TLS connection
ssl::http_get($host, $port, $path)Simple HTTPS GET request

SSL Example

my int $conn = ssl::connect("example.com", 443);
ssl::write($conn, "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
my str $response = ssl::read($conn, 4096);
ssl::close($conn);

# Or use the convenience function:
my str $page = ssl::http_get("example.com", 443, "/");

UTF-8 Introspection (utf8::)

Strada strings carry an internal UTF-8 flag mirroring Perl's SVf_UTF8. When the flag is set, the character built-ins (length, substr, index, rindex, reverse, split, sprintf widths, regex) count Unicode codepoints; when clear, the string is raw bytes. Pure-ASCII strings are character-oriented implicitly. chr(N) for N in 0–127 emits one ASCII byte; for N ≥ 128 it UTF-8-encodes the codepoint and sets the flag (matching use utf8). The byte-level core::byte_* family is available when you need raw byte access for binary protocols.

The flag is set by chr(N>127), the utf8::nfc/nfd/nfkc/nfkd normalizers, and non-ASCII literals in a use utf8 source, and propagates contagiously through concatenation, join, sprintf, and s///. The utf8::* functions below are validation/no-op helpers — they report on the flag rather than transcoding bytes.

FunctionDescription
utf8::is_utf8($str)Returns 1 if string is valid UTF-8, 0 otherwise
utf8::valid($str)Alias for is_utf8()
utf8::encode($str)No-op (strings are already bytes), returns the string
utf8::decode($str)Validates UTF-8; returns 1 if valid, 0 if not
utf8::upgrade($str)No-op (strings are already UTF-8), returns the string
utf8::downgrade($str)Returns string if ASCII-only, dies on non-ASCII
utf8::downgrade($str, 1)With fail_ok=1, returns undef instead of dying
utf8::unicode_to_native($cp)Identity mapping on modern systems
utf8::nfc($str)UAX#15 canonical composition (NFC), Unicode 15.0.0
utf8::nfd($str)Canonical decomposition (NFD)
utf8::nfkc($str)Compatibility composition (NFKC)
utf8::nfkd($str)Compatibility decomposition (NFKD)
utf8::normalize($form, $str)Generic: $form = "NFC"/"NFD"/"NFKC"/"NFKD"

UTF-8 Example

my str $text = "Hello";
say(utf8::is_utf8($text));    # 1 (ASCII is valid UTF-8)
say(utf8::downgrade($text)); # "Hello" (ASCII-only, succeeds)

# Safe downgrade with fail_ok
my scalar $result = utf8::downgrade($text, 1);
if (!defined($result)) {
    say("Contains non-ASCII");
}

Signals

FunctionDescription
core::signal($sig, \&handler)Set signal handler
core::signal($sig, "IGNORE")Ignore signal
core::signal($sig, "DEFAULT")Reset to default

Dynamic Loading (FFI)

FunctionDescription
core::dl_open($lib)Load shared library
core::dl_sym($handle, $name)Get symbol address
core::dl_call_sv($fn, @args)Call Strada function (returns StradaValue)
core::dl_call_int_sv($fn, @args)Call Strada function (returns int)
core::dl_call_str_sv($fn, @args)Call Strada function (returns str)
core::dl_call_void_sv($fn, @args)Call Strada function (void return)
core::dl_call_version($fn)Get library version string
core::dl_close($handle)Unload library

FFI Example

# Load a Strada shared library
my int $lib = core::dl_open("./mylib.so");
my int $fn = core::dl_sym($lib, "my_function");
my scalar $result = core::dl_call_sv($fn, [$arg1, $arg2]);

Library Imports

The plain use statement auto-detects a precompiled sibling artifact (.o preferred over .so) next to the .strada source, with an mtime freshness check. Falls back to source inlining when the artifact is stale or missing.

use lib "lib";
use JSON;                       # picks up lib/JSON.o (or .so) if present

# Explicit forms — useful when no .strada is alongside the artifact:
import_lib "JSON.so";          # Runtime loading (dlopen)
import_object "Utils.o";       # Static linking
import_archive "DataLib.a";   # Static linking with bundled runtime

# Functions are available with namespace syntax:
my str $json = JSON::encode(\%data);

Library Compilation

Compile Strada modules as reusable artifacts:

./strada -M lib/JSON.strada         # module-only JSON.o (recommended)
./strada -M lib/                    # recursive: every .strada → sibling .o
./strada --object-full mylib.strada -o mylib.o  # bundle deps (legacy)
./strada --shared mylib.strada -o mylib.so      # shared object (.so)
./strada --static-lib mylib.strada -o mylib.a   # static archive (includes runtime)

Declaring extern-C Link Deps (link_lib)

A module that wraps a C library advertises its -l deps so consumers don't have to:

package DBI;
link_lib "sqlite3";
link_lib "mysqlclient";
# ... when something does `use DBI;`, the strada driver adds -lsqlite3 -lmysqlclient automatically.

C Interop (__C__ Blocks)

Embed raw C code directly in Strada programs using __C__ blocks:

Top-Level Blocks

For includes, globals, and C helper functions:

__C__ {
    #include <math.h>
    #include <openssl/ssl.h>

    static SSL_CTX *g_ctx = NULL;

    static int helper(int a, int b) {
        return a + b;
    }
}

Statement-Level Blocks

Inline C code inside functions with access to Strada variables:

func my_sqrt(num $x) num {
    __C__ {
        double val = strada_to_num(x);
        return strada_new_num(sqrt(val));
    }
}

Key C Functions

FunctionDescription
strada_to_int(sv)Extract int64_t from StradaValue*
strada_to_num(sv)Extract double from StradaValue*
strada_to_str(sv)Extract string (caller must free!)
strada_new_int(i)Create StradaValue* from int64_t
strada_new_num(n)Create StradaValue* from double
strada_new_str(s)Create StradaValue* from string
&strada_undefReturn undef value

Opaque Handle Pattern

Store C pointers in Strada int variables (64-bit):

func open_connection(str $host) int {
    __C__ {
        char *h = strada_to_str(host);
        SSL *conn = connect_ssl(h);
        free(h);
        // Store pointer as int
        return strada_new_int((int64_t)(intptr_t)conn);
    }
}

func close_connection(int $handle) void {
    __C__ {
        // Retrieve pointer from int
        SSL *conn = (SSL*)(intptr_t)strada_to_int(handle);
        SSL_free(conn);
        return &strada_undef;
    }
}

JSON Functions

FunctionDescription
JSON::encode($val)Convert to JSON string
JSON::decode($str)Parse JSON string

Package Syntax

SyntaxDescription
__PACKAGE__Current package name (runtime)
::func()Call func in current package (compile-time)
.::func()Alternate syntax for above
__PACKAGE__::func()Explicit form of above
use overload "+" => "method", ...;Operator overloading for current package

Example

package Calculator;

func add(int $a, int $b) int { return $a + $b; }

func compute(int $x, int $y) int {
    return ::add($x, $y);  # Calls Calculator_add
}

Moose-Style OOP Keywords

Strada provides a declarative OOP system inspired by Perl's Moose. See the OOP page for full details and examples.

SyntaxDescription
has ro type $name;Declare read-only attribute with getter
has rw type $name;Declare read-write attribute with getter and setter
has ro type $name (required);Required attribute (must be passed to constructor)
has rw type $name = default;Attribute with default value
extends Parent;Inherit from one or more parent classes
extends Parent1, Parent2;Multiple inheritance
with Role;Compose a role (mixin) into the class
before "method" func($self) void { }Run code before a method call
after "method" func($self) void { }Run code after a method call
around "method" func($self) void { }Wrap a method call entirely
Auto-Generated Constructor

When a package uses has declarations, the compiler automatically generates a new() constructor that accepts named arguments as alternating key-value pairs. If you define your own new(), the auto-generated one is skipped.

my scalar $obj = MyClass::new("name", "value", "age", 30);

core:: Namespace Alias

The core:: namespace is the preferred way to call system functions. It is an alias for the older sys:: namespace. The compiler normalizes core:: to sys:: at compile time, so there is zero overhead. Both namespaces work interchangeably.

core:: Call (preferred)Legacy sys:: Call
core::exit(0)sys::exit(0)
core::open($path, "r")sys::open($path, "r")
core::time()sys::time()
core::getenv("HOME")sys::getenv("HOME")
core::fork()sys::fork()

Use whichever namespace feels more natural. core:: is recommended for new code as it reads more clearly as "core language functionality."

# These are equivalent:
my int $pid = core::fork();
my int $pid = sys::fork();

my str $home = core::getenv("HOME");
my str $home = sys::getenv("HOME");

my int $now = core::time();
my int $now = sys::time();

Miscellaneous

FunctionDescription
dump($val)Debug print value structure
caller()Get caller information
eval($code)Evaluate Strada code string
$obj->isa($class)Check if object is instance of class
$obj->can($method)Check if object has method
$obj->$method()Dynamic method dispatch (name from variable)
local($var)Dynamic scoping for our variables

local() — Dynamic Scoping

The local() function provides dynamic scoping for our (package-global) variables. It saves the current value and automatically restores it when the enclosing scope exits. This is useful for temporarily overriding globals without affecting the rest of the program.

our int $verbose = 0;

func debug_section() void {
    local($verbose) = 1;  # Temporarily set to 1
    do_work();               # $verbose is 1 here
    # $verbose automatically restored to 0 on scope exit
}

func do_work() void {
    if ($verbose) {
        say("Doing work...");  # Prints when called from debug_section
    }
}

func main() int {
    do_work();        # $verbose is 0, nothing printed
    debug_section(); # $verbose is temporarily 1 inside
    do_work();        # $verbose is 0 again
    return 0;
}
local() vs my

local() provides dynamic scoping — the localized value is visible in the current function and all functions called from it. my provides lexical scoping — the variable is only visible in the current block. local() only works with our variables (package globals).

tie/untie/tied — Tied Hashes

The tie mechanism binds a hash variable to a class, allowing custom behavior for hash operations. When a hash is tied, all accesses (read, write, delete, exists, iteration) are dispatched to methods in the tied class.

FunctionDescription
tie(%hash, "ClassName", @args)Bind hash to class; calls TIEHASH(@args)
untie(%hash)Unbind hash from class
tied(%hash)Return the tied object, or undef if not tied

TIEHASH Methods

The tied class must implement these methods:

MethodDescription
TIEHASH(@args)Constructor — called by tie(), returns the tied object
FETCH($self, $key)Called when reading: $hash{$key}
STORE($self, $key, $val)Called when writing: $hash{$key} = $val
DELETE($self, $key)Called for: delete($hash{$key})
EXISTS($self, $key)Called for: exists($hash{$key})
FIRSTKEY($self)Called to start iteration (keys, each)
NEXTKEY($self, $lastkey)Called for subsequent keys during iteration
CLEAR($self)Called when hash is cleared

Example: Case-Insensitive Hash

package CIHash;

func TIEHASH() scalar {
    my hash %self = ();
    $self{"data"} = {};
    return bless(\%self, "CIHash");
}

func FETCH(scalar $self, str $key) scalar {
    return $self->{"data"}->{lc($key)};
}

func STORE(scalar $self, str $key, scalar $val) void {
    $self->{"data"}->{lc($key)} = $val;
}

package main;

func main() int {
    my hash %h = ();
    tie(%h, "CIHash");

    $h{"Name"} = "Alice";   # Calls CIHash::STORE
    say($h{"name"});         # Calls CIHash::FETCH -> "Alice"
    say($h{"NAME"});         # "Alice" (case insensitive)

    untie(%h);              # Unbind from class
    return 0;
}
Zero Overhead

When a hash is not tied, hash operations compile to the same code as before — no dispatch checks, no extra branches. The tied mechanism only adds overhead to hashes that are actually tied.

Compiler Flags

The Strada compiler (stradac) and wrapper (strada) support these flags:

FlagDescription
-r, --runCompile and run immediately
-c, --keep-cKeep generated .c file
-g, --debugInclude debug symbols
-p, --profileEnable function profiling (report to stderr at exit)
--full-profileLine-level profiling (writes strada-prof.out; implies -g)
-w, --warningsShow compiler warnings
-t, --timingShow compilation phase timing
--sharedCompile as shared library (.so)
-L <path>Add library search path (high priority)
-LL <path>Add library search path (low priority)

Examples

# Compile and run
./strada -r program.strada

# Compile with debugging
./strada -g program.strada

# Compile with function profiling
./strada -p program.strada
./program  # Prints profiling report on exit

# Compile with line-level profiling
./strada --full-profile program.strada
./program                                    # Writes strada-prof.out
strada-proftext strada-prof.out              # Text report
strada-profhtml strada-prof.out profhtml/    # HTML report

# Check for warnings
./strada -w program.strada

# Create shared library
./strada --shared mylib.strada  # Creates mylib.so