Program flow

P

Program flow and control structures

Control structures in Kaya are similar to their equivalents in most other imperative languages.

Conditional execution (if/else)

Conditional execution is achieved using an if...else expression.

if (test) {
    expression1;
} else if (test2) {
    expression2;
} else {
    expression3;
}

For example:

Int cmp(Int a, Int b) {
    if (a < b) {
        return -1;
    } else if (a > b) {
        return 1;
    } else {
        return 0;
    }
}

Iteration (for loops)

The usual form of iteration in Kaya is iteration over the contents of an array, taking the form.

for variable in array {
    expression;
}

The expression must be of type Void. For example, the following function prints out the contents of an array of integers

Void printArray([Int] xs) {
    for x in xs {
	putStrLn(String(x));
    }
}

You can easily iterate across a range of numbers by using the range syntax for arrays:

for i in [1..x] {
    putStrLn(String(i));
}

This is usually preferable to a C-style for loop. Note that the compiler will optimise this, so you can do for i in [1..1000000] without actually taking up most of a megabyte with the array!

It is sometimes useful, while iterating over an array, to have an index counter. For example, the printArray() function above could be modified to

Void printArray([Int] xs) {
    for x@i in xs {
	putStrLn("Item "+i+" is "+x);
    }
}

The index starts at zero for the first element of the array, and the index variable is only in scope during the loop.

C-style for loops

C-style for loops are available for situations where array iteration is not appropriate. Generally iterating over an array directly is better, if possible.

for (initial ; test ; increment) {
    expression;
}

For example:

for (i = 1; i < 1000; i = i*2) {
    putStrLn(String(i));
}

Looping (while)

You can loop while a condition is true using the while or do...while loops.

while (test) {
    expression;
}

The test must be of type Bool and the expression of type Void. The expression will be evaluated as long as the test returns true. If the expression should always be evaluated at least once, use the do...while form.

do {
    expression;
} while (test)

For example, the following code will print a (non-binary) file.

while (!eof(file)) {
    putStrLn(read(file));
}

The eof and read functions are from the IO standard library module.

Exception handling (try/catch)

The current Exception system was introduced in Kaya 0.2.4. Older code may use old-style Exceptions (though should be migrated as these are deprecated and will be removed in Kaya 0.3.0)

Before an Exception can be used, it must be defined. This is done using a top-level declaration in the program or module. Exceptions may be given parameters which can be used to provide more information about the cause of the Exception.

Exception OutOfCheese(Cheese cheese, Int gramsrequired);
Exception InitialisationFailed();

Once defined, the Exception can then be thrown by code as required.

Exception DivByZero();

Int safeDivide(Int num, Int den) {
    if (den == 0) {
        throw(DivByZero());
    } 
    return num/den;
}

This function checks if you attempt to divide by zero. If so, the exception is thrown. If the exception is not caught by the function that generated it, it is passed up the call stack until a function does catch it. If no functions catch it, the program exits, printing a backtrace of the exception. The parameters of the Exception are also extracted at the catching stage.

try {
    a = safeDivide(num,den);
} catch(DivByZero) { 
    putStrLn("You can't divide by zero!");
} catch(AnotherError(a,b)) {
    putStrLn("Another error occurred: "+a+" was equal to "+String(b));
} catch(e) {
    putStrLn("The unexpected error "+exceptionMessage(e)+" occurred!");
}

The code above tries to divide the numbers. If an Exception is thrown, it is then checked to see if it matches each of the catch blocks in turn. The action of the first matching block will then be carried out.

If none of the blocks with named exceptions match (or there are no such blocks), then there may be a ‘catch-all’ case at the end (if it is not at the end, any following catch blocks are ignored). The exception will be assigned to the variable named in the ‘catch-all’ case, and you can use the exceptionMessage and exceptionBacktrace functions to debug the error.

If the Exception is not caught as a named Exception, and there is no catch-all block, then the program will proceed to the next outermost try/catch statement to test there.

Older Kaya code may have old-style Exceptions. These cannot be caught as named exceptions, and will be removed entirely in version 0.3.0. It is generally straightforward to replace these with the current Exception syntax.

Recent Comments

No comments to show.

Pages