A Tour of Morfa

Properties

Properties are functions that are used as if they were variables or fields, from the point of view of syntax.

Properties are declared using the keyword property instead of func.

A read property is a function that takes no arguments and returns a type other than void. Calling a read property looks like reading a variable or field with the same name.

struct Creature 
{ 
    var name: text; 

    var species: text;

    // Declare a read property
    property description(): text 
    {
        return name ~ " the " ~ species;
    }
}

unittest  
{
    var jake = Creature("Jake", "dog");
    // description is accessed like a field:
    assert (jake.description == "Jake the dog");
}

A write property is a void function with a single parameter. Calling a write property looks like variable or field assignment.

struct Angle
{
    var radians: float; 

    // Declare a write property
    property degrees(value: float): void
    {
        radians = value * 3.14159 / 180;
    }
}

unittest
{
    var a: Angle;
    a.degrees = 60.0;
    assert (a.radians == 3.14159 / 3);
}

Overloading properties

You may overload a property with another property (but not with a non-property function!). In the following example there is a read property and two write properties called value:

import morfa.Text.decoders: decodeUtf8;

struct String
{
    var bytes: int8[];

    property value(bs: int8[]): void
    {
        bytes = bs.dup;
    }   

    property value(txt: text): void
    {
        bytes = txt.encodeUtf8;
    }   

    property value(): text
    {
        return decodeUtf8(bytes);
    }   
}

unittest
{
    var s1: String;
    s1.value = "Morfa";

    var s2: String;
    s2.value = [77, 111, 114, 102, 97];

    assert (s1.value == s2.value);
}

Top level properties

Although properties are typically members of structs or classes, you may declare a property on the top level of a module.

var counter = 0;

property uniqueId(): int
{
    counter += 1;
    return counter;
}

unittest
{
    var id1 = uniqueId;
    var id2 = uniqueId;
    assert (id1 != id2);
}

Reserved property names

Certain names are reserved for builtin properties. Examples are init (a builtin property of every type) or classinfo (a builtin property of class instances). Compiler will not allow you to use them for defining your own properties.

TODO: add reference to the list of built-in type properties.