A Tour of Morfa

Class operators

Operators may be overloaded and declared as class or structure members, with all the consequences one might expect. Lets go through this step-by-step.

class A
{
    operator @ { kind = prefix, precedence = mul }
    static func @ (i: int): A[]
    {
        return new A[i];
    }
}

In the above example we have introduced an operator @ and bound it to a function which produces an array of A objects of length i. Note here that:

  • The operator @ is declared within class, so it will only be visible inside methods of A and its subclasses.
  • func @ is declared static so it does not access any instance of A.
unittest
{
    var myAinstance = new class A
    {
        var children: A[];
        func new()
        {
            children = @ 2;
        }
    };
}

A consequence of dropping the static modifier of func @ is that @ will work on the B's instance (and have access to this).

class B
{
    operator @ { kind = prefix, precedence = mul }
    func @ (i: int): B[]
    {
        var ret = new B[i + 1];
        ret[0] = this;
        return ret;
    }
}

unittest
{
    var myBinstance = new class B
    {
        var childrenAndMe: B[];
        func new()
        {
            childrenAndMe = @ 2;
        }
    };
}

Note well that the arguments of an operator function have absolutely nothing to do with the owner class. This distinguishes Morfa's operator overloading greatly from the model adopted in C++.

import morfa.base;
class C
{
    func +(someCinstance: C): void
    {
        println("I have access to", addressof this, 
                "and I shall be called by +c inside non-static methods of C",
                "and its subclasses");
    }
    static func -(someCinstance: C): void
    {
        println("I don't have access to this and I shall be called by -c inside",
                "methods of C and its subclasses.",
                "I am called - to avoid conflict with my non-static brother +");
    }
    static func $+(someCinstance: C): void
    {
        println("I don't have access to this", 
                "and I shall be called by c+ inside methods of C and its subclasses");
    }
}

func +(someCinstance: C, someOtherCinstance: C): void
{
    println("I operate on two instances of C",
            "and I shall be called by c+c wherever I am accessible");
}