Skip to content

Condition Operators

if

Syntax options: * if (bool) statement; * if (bool) statement; else statement; * if (bool) statement; elseif statement; else statement;

Example:

> if (1==0) "1==0\n".echo();  else "none\n".echo();
none

> if (1==0) "1==0\n".echo(); elseif (2==2) "2==2\n".echo(); else "none\n".echo();
2==2

switch

Syntax options: * switch (item) {case condition1: statement; case condition2: statement; etc...;}; * switch (item) {case condition1: statement; case condition2: statement; etc...; default: statement;};

Grapa's switch statement is much more powerful than traditional switch statements. Each case can contain a full expression that returns true/false, and evaluation stops at the first match.

Basic Value Matching

/* Traditional value matching */
switch (x) {
    case 1: "One".echo();
    case 2: "Two".echo();
    default: "Other".echo();
};

Switch Statement Syntax

Single command in case:

switch (x) {
    case 10: "x is 10".echo();
    case 5: "x is 5".echo();
    default: "x is something else".echo();
};

Multiple commands in case (must use {}):

switch (x) {
    case 10: {
        "x is 10".echo();
        "Additional handling".echo();
    }
    case 5: {
        "x is 5".echo();
        "More handling".echo();
    }
    default: {
        "x is something else".echo();
        "Default handling".echo();
    }
};

Boolean Expression Matching

/* Each case can be a full boolean expression */
switch (true) {
    case (x < 0): "Negative".echo();
    case (x == 0): "Zero".echo();
    case (x > 0): "Positive".echo();
    default: "Unknown".echo();
};

Complex Pattern Matching

/* Pattern matching on data structures */
user = {name: "Alice", age: 25, role: "admin"};

switch (true) {
    case (user.role == "admin" && user.age >= 18): "Admin access granted".echo();
    case (user.role == "user" && user.age >= 18): "User access granted".echo();
    case (user.age < 18): "Access denied - too young".echo();
    default: "Access denied - unknown role".echo();
};

Variable Declaration in Switch Expression

Grapa's switch statement can declare and initialize variables directly in the switch expression, enabling advanced pattern matching and fuzzy matching:

/* Declare variable in switch expression for advanced matching */
switch(a:[1,3,5]) {
    case (a[2]==5): "Array element matches".echo();
    default: "No match found".echo();
};

Advanced Pattern Matching Examples:

/* Fuzzy string matching */
switch(input:"hello world") {
    case (input.grep("hello", "i")): "Contains 'hello' (case insensitive)".echo();
    case (input.len() > 10): "Long string".echo();
    default: "No pattern match".echo();
};

/* Complex data structure analysis */
switch(data:{name: "Alice", scores: [85, 92, 78]}) {
    case (data.scores.mean()[0] >= 90): "High performer".echo();
case (data.scores.mean()[0] >= 80): "Good performer".echo();
    case (data.scores.min() < 70): "Needs improvement".echo();
    default: "Average performer".echo();
};

/* Array pattern matching */
switch(arr:[1,2,3,4,5]) {
    case (arr.len() == 5 && arr[0] == 1): "Five-element array starting with 1".echo();
    case (arr.sum() > 10): "Array sum greater than 10".echo();
    case (arr.grep(3)): "Array contains 3".echo();
    default: "No specific pattern".echo();
};

Key Benefits: - Local scope: Variables are only available within the switch statement - Advanced matching: Enables fuzzy matching, pattern recognition, and complex conditions - Clean syntax: No need to declare variables before the switch - Temporary variables: Perfect for one-off calculations in switch logic

Type-Based Matching

/* Match based on data type */
switch (true) {
    case (data.type() == $STR): "String data".echo();
    case (data.type() == $INT): "Integer data".echo();
    case (data.type() == $ARRAY): "Array data".echo();
    case (data.type() == $LIST): "List data".echo();
    default: "Other data type".echo();
};

Exception Handling: try/catch/finally/throw

Grapa provides comprehensive exception handling with try/catch/finally blocks and throw statements.

Basic Exception Handling

/* Basic try/catch with finally */
try {
    throw 'error message';
} {
    catch 'error message': 'Caught specific error'.echo();
    default: 'Caught any other error'.echo();
} finally: 'Always executed'.echo();

Exception with Variable Binding

/* Throw with variable binding for detailed error handling */
try {
    throw (err:'error message');
} {
    catch (err.left(1)=='e'): 'Error starts with e: '.interpolate({msg=err}).echo();
    catch (err.len() > 10): 'Long error message'.echo();
    default: 'Caught other error'.echo();
} finally: 'Cleanup completed'.echo();

Object Variable Binding

/* Direct object throw - works correctly */
try {
    user = {name: 'Alice', age: 30};
    throw (err:user);
} {
    default: ('User name: ' + err.name).echo();
}

/* Nested object with explicit copy - works correctly */
try {
    user = {name: 'Alice', age: 30};
    throw (err:{user: user.list()});
} {
    default: ('User name: ' + err.user.name).echo();
}

/* Nested object without copy - works correctly */
try {
    user = {name: 'Alice', age: 30};
    throw (err:{user: user});  /* Local variable references are now preserved */
} {
    default: ('User name: ' + err.user.name).echo();
}

Note: Local variable references in thrown objects are now automatically preserved. The .list() method is no longer required for reliable binding.

Multiple Catch Blocks

/* Multiple catch blocks with different conditions */
try {
    throw 'network error';
} {
    catch 'network error': 'Network issue handled'.echo();
    catch 'file error': 'File issue handled'.echo();
    catch (true): 'Any other error handled'.echo();
} finally: 'Resource cleanup'.echo();

Exception Handling Syntax

Basic throw:

throw 'error message';
throw (err:'error message');  // With variable binding

Try/catch/finally:

try {
    // Code that might throw
} {
    catch 'error': 'Handle specific error'.echo();
    catch (condition): 'Handle based on condition'.echo();
    default: 'Handle any other error'.echo();
} finally: 'Always execute'.echo();

Key Features: - Variable binding: Variables declared in throw are accessible in catch blocks - Flexible matching: Catch conditions can be constants, expressions, or complex patterns - Multiple catch blocks: Can have multiple catch conditions - Finally block: Always executes regardless of exception - Consistent syntax: Follows the same pattern as switch/case statements - No parentheses required: Simple constants don't need parentheses

Sequential Evaluation (First Match Wins)

/* Evaluation stops at first true condition */
switch (true) {
    case (x > 10): "Greater than 10".echo();  /* If x=15, only this executes */
    case (x > 5): "Greater than 5".echo();    /* This won't execute if above is true */
    case (x > 0): "Greater than 0".echo();    /* This won't execute if above is true */
    default: "Zero or negative".echo();
};

Key Features: - Implicit break: No break statements required, execution stops after first match - Multiple commands: Must be enclosed in {} when case contains multiple statements - Full expressions: Each case can contain complex boolean expressions - Sequential evaluation: Evaluates from first to last case, stops at first match - No fall-through: Unlike C-style switches, Grapa doesn't fall through to next case - Pattern matching: Can match on data structure patterns, types, and conditions - Default case: Optional catch-all for unmatched conditions

?

Syntax options: * bool ? statement for true; * bool ? statement for true : statement for false; * bool ? : statement for false; * (<0)|(0)|(>0) ? statement for -1 : statement for 0 : statement for 1;

Example:

> 1?hi:by
hi

> 0?hi:by
by

> -55?hi:by:there
hi

> ("a"<=>"b")?a:e:b
a


See also