Skip to content

Control Flow

Nic provides familiar control flow constructs: conditionals, loops, and match expressions.

If-Else

nic
fn classify(n: i32) -> string {
    if n > 0 {
        return "positive";
    } else if n < 0 {
        return "negative";
    } else {
        return "zero";
    }
}

fn main() -> unit {
    println(classify(42));   // positive
    println(classify(-5));   // negative
    println(classify(0));    // zero
    return;
}

Conditions don't need parentheses, but braces {} are required.

While Loops

nic
fn main() -> unit {
    let i: i32 = 0;
    
    while i < 5 {
        println("iteration");
        i = i + 1;
    }
    
    return;
}

For Loops

C-style for loops with three parts: initialization, condition, and update:

nic
fn main() -> unit {
    for let i: i32 = 0; i < 10; i = i + 1 {
        println("counting");
    }
    
    return;
}

Note: The loop variable is declared with let inside the for statement.

Break and Continue

Exit a loop early with break, skip to the next iteration with continue:

nic
fn main() -> unit {
    for let i: i32 = 0; i < 100; i = i + 1 {
        if i == 5 {
            continue;  // skip 5
        }
        if i == 10 {
            break;     // stop at 10
        }
        println("processing");
    }
    
    return;
}

Match Expressions

Pattern matching is the most powerful control flow in Nic. Match on values, types, and structure:

nic
fn describe(n: i32) -> string {
    return match n {
        0 -> "zero",
        1 -> "one",
        2 -> "two",
        _ -> "many"
    };
}

fn main() -> unit {
    println(describe(0));  // zero
    println(describe(1));  // one
    println(describe(42)); // many
    return;
}

The _ wildcard matches anything. Match expressions must be exhaustive—all possible values must be covered.

Match with Guards

Add conditions to match arms with if:

nic
fn classify_number(n: i32) -> string {
    return match n {
        0 -> "zero",
        x if x > 0 && x < 10 -> "small positive",
        x if x >= 10 -> "large positive",
        _ -> "negative"
    };
}

Match in Statements

Use match as a statement for side effects:

nic
fn handle(code: i32) -> unit {
    match code {
        0 -> println("success"),
        1 -> println("warning"),
        _ -> println("error")
    };
    return;
}

Nested Conditionals

nic
fn check(a: bool, b: bool) -> string {
    if a {
        if b {
            return "both true";
        } else {
            return "only a";
        }
    } else {
        if b {
            return "only b";
        } else {
            return "neither";
        }
    }
}

Summary

ConstructSyntax
If-elseif cond { } else { }
Whilewhile cond { }
Forfor let i = 0; i < n; i = i + 1 { }
Breakbreak;
Continuecontinue;
Matchmatch value { pattern -> expr, ... }
Guardpattern if condition -> expr

Next

Learn about Structs to create your own data types.

Released under the MIT License.