MALDA™ Reference Manual

The AI-First Programming Language - Version 1.0.11

5. Variables

5.1 Variable Declaration

Variables in MALDA are declared using the var keyword followed by the variable name and an optional initial value:

var x = 10;
var name = "Alice";
var isActive = true;
var pi = 3.14159;

Variables must be declared before use. The type is inferred from the initial value. For bindings that must never be reassigned, use const instead of var (see 5.3 Constant Declarations).

You may optionally add an informational type hint after the name. At interpret-time hints are documentation for you and the IDE, not runtime checks:

var name: Type? = value;

Example: var count: int = 0;, var msg: string = "hello";, or var p: Person = new Person();

Toolchain: CLI --strict-types turns hint mismatches into analysis Errors. malda compile --mode transpile and publish refuse emit when analysis reports Errors; --lenient-types skips that gate. Known hint names include Tier 0 primitives (int, string, …), declared class/schema/sum-type names (same unit or imported modules), and built-in host classes (for example RestServer). The language server emits an Error by default when a hint disagrees with a literal, a new ClassName() expression, another identifier that carries a known hint, or a call result whose callee declares a return hint (for example var n: int = "abc";, var p: Person = 1;, n = s; when s: string, or var n: int = make(); when make() -> string). The same check covers assignments, call arguments, and return values against parameter/-> hints. Operators and built-in return types are not inferred.

5.2 Variable Assignment

After declaration, variables can be reassigned using the assignment operator =:

x = 20;
name = "Bob";
x = x + 1;

5.3 Constant Declarations

A binding declared with const instead of var cannot be reassigned. An initializer is required:

const MAX_RETRIES = 3;
const APP_NAME = "malda-demo";

print(MAX_RETRIES);   // 3

Attempting to assign to a constant is a runtime error that names the binding:

const limit = 10;
limit = 20;   // Runtime error: Cannot assign to const 'limit'.

Compound assignment (+=) and the increment operators are assignments too, so they fail on a constant for the same reason.

Constants Are Shallow

const freezes the binding, not the value it points to. A constant that holds an array, dictionary, or object still allows the contents to change:

const config = dict { "retries": 3 };

config["retries"] = 5;   // Allowed: the dictionary is mutated, not the binding
print(config["retries"]); // 5

// config = dict { };    // Runtime error: Cannot assign to const 'config'.

Scope and Shadowing

Constants follow the same block scoping as var, and an inner scope may shadow an outer constant with its own binding:

const mode = "prod";

function describe() {
    var mode = "local";   // Shadows the outer constant inside this function
    return mode;
}

print(describe());   // "local"
print(mode);         // "prod"
When to reach for it: use const for configuration values, limits, and lookup tables that must not drift during a run. Everything else stays var; MALDA does not require constants and does not optimize differently for them.

5.4 Destructuring

Destructuring allows you to extract values from arrays and objects into individual variables in a single statement.

Array Destructuring

Extract elements from an array into variables:

var arr = [10, 20];
var [x, y] = arr;
print(x);  // Prints: 10
print(y);  // Prints: 20

Rest Pattern: Use ...rest to capture remaining elements:

var arr = [1, 2, 3, 4, 5];
var [first, second, ...rest] = arr;
// first = 1, second = 2, rest = [3, 4, 5]
print(length(rest));  // Prints: 3

Notes:

Object Destructuring

Extract properties from an object into variables:

var user = { name: "Alice", age: 30, role: "admin" };
var { name, age } = user;
print(name);  // Prints: "Alice"
print(age);   // Prints: 30

Renaming: Extract properties with different variable names:

var user = { name: "Bob", age: 25 };
var { name: userName, age: userAge } = user;
print(userName);   // Prints: "Bob"
print(userAge);    // Prints: 25

Nested Destructuring: Extract from nested objects:

var data = {
    user: { name: "Charlie", age: 35 },
    role: "admin"
};
var { user: { name, age }, role } = data;
print(name);   // Prints: "Charlie"
print(age);    // Prints: 35
print(role);   // Prints: "admin"

Destructuring Assignment

You can also use destructuring with assignment (for existing variables):

var x = 0;
var y = 0;
var arr = [10, 20];
[x, y] = arr;  // Assigns 10 to x, 20 to y
print(x + y);  // Prints: 30
var name = "";
var age = 0;
var user = { name: "David", age: 40 };
{ name, age } = user;  // Assigns properties to variables
print(name);  // Prints: "David"
print(age);   // Prints: 40

Destructuring from Function Returns

Destructure values returned from functions:

function getPoint() {
    return { x: 5, y: 10 };
}

var { x, y } = getPoint();
print(x + y);  // Prints: 15

Error Handling

If a destructuring pattern doesn't match (e.g., array too short, missing object property), a runtime error is thrown:

try {
    var arr = [1, 2];
    var [x, y, z] = arr;  // Error: array has only 2 elements
} catch (e) {
    print("Destructuring failed: " + e);
}
Destructuring Tips:

5.5 Variable Scope

Variables in MALDA are block-scoped. A variable is accessible within the block where it is declared and any nested blocks.

Global Variables

Variables declared outside functions are global and accessible throughout the program:

var globalVar = 10;

function test() {
    print(globalVar);  // Can access global variable
}

test();

Local Variables

Variables declared inside a function are local to that function:

function test() {
    var localVar = 20;
    print(localVar);  // Can access local variable
}

// print(localVar);  // Error: localVar is not accessible here

Variable Shadowing

Local variables shadow global variables with the same name:

var x = 10;  // Global variable

function test() {
    var x = 20;  // Local variable shadows global x
    print(x);    // Prints 20 (local)
}

test();
print(x);  // Prints 10 (global)

Block Scope

Variables declared in blocks (if, while, for) are scoped to that block:

if (true) {
    var blockVar = 30;
    print(blockVar);  // Can access blockVar
}

// print(blockVar);  // Error: blockVar is not accessible here

See Also