A Tour of Morfa

Default parameter values

A template may declare the default value for its parameter.

operator <: { kind = infix, precedence = compare }

template <T, O = DefaultOrder>
func findMax(arr: T[]): T
{
    alias <: = O.ordered; 
    var max = T.init;
    for (a in arr)
        if (max <: a) max = a;
    return max;
}

struct DefaultOrder
{
    template <T>
    static func ordered(a: T, b: T): bool
    {
        return a <= b;
    }
}

If you provide only one template argument for findMax, the parameter O will be bound to its default value DefaultOrder:

unittest
{
    // findMax<int> is equivalent to findMax<int, DefaultOrder>
    assert (findMax<int>([1,0,3,2]) == 3); // 
}

If you omit the arguments, the compiler will try to deduce T from the function argument and will bind O to DefaultOrder:

unittest
{
    assert (findMax([1,0,3,2]) == 3);
}

You may also instantiate findMax with two arguments:

unittest
{
    assert (findMax<int,ReverseOrder>([1,0,3,2]) == 0);
}

struct ReverseOrder
{
    template <T>
    static func ordered(a: T, b: T): bool
    {
        return b <= a;
    }
}