Language Basics

Core syntax and fundamental concepts of Strada.

Program Structure

A Strada program consists of function definitions. Execution begins at the main function:

# Comments start with #

func helper() void {
    say("I'm a helper function");
}

func main() int {
    helper();
    say("Hello from main!");
    return 0;
}

Statements

Statements end with semicolons:

my int $x = 10;
say($x);
$x = $x + 1;

Comments

# This is a single-line comment

my int $x = 42;  # Inline comment

Operators

Arithmetic Operators

Operator Description Example
+Addition$a + $b
-Subtraction$a - $b
*Multiplication$a * $b
/Division$a / $b
%Modulo$a % $b
**Exponentiation$a ** $b

Comparison Operators

Numeric String Description
==eqEqual
!=neNot equal
<ltLess than
>gtGreater than
<=leLess than or equal
>=geGreater than or equal
<=>cmpSpaceship (returns -1, 0, or 1)
Spaceship operators: Use <=> for numeric sort and cmp for string sort: sort { $a <=> $b; } @nums or sort { $a cmp $b; } @strings
Important Use eq/ne for string comparison, not ==/!=. Using numeric operators on strings compares them numerically.

Logical Operators

Operator Description Example
&&Logical AND (returns boolean)$a && $b
||Logical OR (returns value)$h{"key"} || "default"
//Defined-or$h{"key"} // "default"
!Logical NOT!$a
andLow-precedence AND$a and $b
orLow-precedence OR$a or $b
notLow-precedence NOTnot $a
|| vs //: The || operator returns its left operand if truthy, otherwise its right operand (like Perl/JavaScript). The // operator returns its left operand if defined (not undef), otherwise its right operand. Use // when you want empty strings or zero to be considered valid values.

String Operators

Operator Description Example
.Concatenation"Hello" . " World"
xRepetition"ab" x 3"ababab"

Bitwise Operators

Operator Description Example
&Bitwise AND$a & $b
|Bitwise OR$a | $b
^Bitwise XOR$a ^ $b
~Bitwise NOT~$a
<<Left shift$a << 2
>>Right shift$a >> 2

Increment/Decrement

my int $i = 0;

$i++;    # Postfix increment (returns old value)
$i--;    # Postfix decrement
++$i;    # Prefix increment (returns new value)
--$i;    # Prefix decrement

Assignment Operators

$x = 10;     # Assignment
$x += 5;    # Add and assign ($x = $x + 5)
$x -= 3;    # Subtract and assign
$x *= 2;    # Multiply and assign
$x /= 4;    # Divide and assign
$x .= "!";  # Concatenate and assign

Ternary and Other Operators

# Ternary conditional
my str $result = $x > 0 ? "positive" : "non-positive";

# Range operator (creates array)
my array @nums = (1..10);

# Reference operator
my int $x = 42;
my scalar $ref = \$x;      # Reference to $x

# Function reference
my scalar $fn = &my_function;

Blocks

Blocks are delimited by curly braces and create a new scope:

{
    my int $x = 10;  # $x only visible in this block
    say($x);
}
# $x is not accessible here

Truthiness

Values are considered "false" if they are:

Everything else is "true".

if ($value) {
    say("Value is true");
} else {
    say("Value is false");
}

Magic Namespaces

Built-in functions are organized into namespaces:

Core Functions (No Namespace)

Common functions like say(), print(), push(), pop(), len(), etc.

math:: Namespace

math::sin(3.14)
math::cos(0)
math::sqrt(16)
math::pow(2, 10)
math::abs(-5)
math::floor(3.7)
math::ceil(3.2)

core:: Namespace

core:: is the preferred namespace for system functions. (sys:: also works for backwards compatibility.)

core::open("file.txt", "r")
core::read($fd, 1024)
core::write($fd, $data)
core::close($fd)
core::fork()
core::exec("ls", ["-la"])
core::getenv("PATH")
core::time()

Regex Operations

Pattern Matching

my str $s = "Hello World";

# Match
if ($s =~ /World/) {
    say("Found it!");
}

# Negated match
if ($s !~ /Goodbye/) {
    say("Not found");
}

Substitution

my str $s = "Hello World";

# Replace first occurrence
$s =~ s/World/Strada/;

# Replace all occurrences (g flag)
$s =~ s/l/L/g;

# Case-insensitive (i flag)
$s =~ s/hello/Hi/i;

Input/Output

Console Output

say("With newline");      # Prints with newline
print("No newline");      # Prints without newline

File I/O

# Read entire file
my str $content = slurp("file.txt");

# Write to file
spew("output.txt", $content);

# Low-level file operations
my scalar $fh = core::open("file.txt", "r");
my str $data = core::readline($fh);
core::close($fh);

Diamond Operator <$fh>

Read lines from filehandles using the Perl-style diamond operator:

# Scalar context: read one line at a time
my scalar $fh = core::open("input.txt", "r");
my str $line = <$fh>;
while (defined($line)) {
    say($line);
    $line = <$fh>;
}
core::close($fh);

# Array context: read ALL lines at once
$fh = core::open("input.txt", "r");
my array @lines = <$fh>;    # Reads entire file!
core::close($fh);

foreach my str $line (@lines) {
    say($line);
}

Print/Say to Filehandle

Write to files or sockets using say/print with a filehandle as the first argument:

# Write to file
my scalar $out = core::open("output.txt", "w");
say($out, "Line with newline");    # Adds \n
print($out, "No newline");          # No \n
core::close($out);

# Also works with sockets!
my scalar $sock = core::socket_client("localhost", 80);
say($sock, "GET / HTTP/1.0");
my str $response = <$sock>;    # Read response
core::socket_close($sock);