27: Contracts - royal-lang/rl GitHub Wiki

Contracts are useful for contract creation on types and function. These can help debugging and also making sure values, types etc. satisfies the given type or function's contract.

Invariants (Type Contracts)

Contracts for types like structs are called invariants. The type's invariant can be used to validate that members of the type satisfied the contract of the type. The invariant is called every time a property of the type is set.

struct NAME // Or: ref struct NAME
{
    invariant
    {
        ASSERTS
    }
}

Example:

ref struct Date
{
    prop int day { get; set; }
    prop int hour { get; set; }

    invariant
    {
        assert(day >= 1 && day <= 31);
        assert(hour >= 0 && hour < 24);
    }
}

Contracts (Function Contracts)

Function contracts are created using nested functions with special names.

For the in contract simply create a scope using the in keyword and for return / out contracts create a scope using the return keyword.

fn NAME()
{
    in
    {
        ASSERTS
    }

    return // Using return as a variable in the body will yield the return value.
    {
        ASSERTS
    }

    return(RETURNVALUE_NAME)
    {
        ASSERTS
    }
}

Example:

fn int div(int x, int y)
{
    in
    {
        assert(x != 0 && y != 0);
    }

    return(int returnValue)
    {
        assert(returnValue > 0);
    }

    return x / y;
}
var result = div(10, 10); // Ok.

...

var result = div(10, 20); // Assert error from return();

...

var result = div(0, 5); // Assert error from in();