The Freya Programming Language

Nested types

See also

Most types are declared inside the scope of a namespace. However, types can also be declared inside class and record declarations, as nested types

Syntax

There are two syntactic variants for declaring a nested type:

  1. Nesting the whole inner type declaration inside the outer type declaration
  2. Declaring a stub inside the outer type, as a forward reference, and providing the final declaration outside the outer class.

This code fragment shows the declaration of a generic Stack class, including the declaration of a nested Node class:

Stack = sealed class[X]
private
    Node = sealed class
    public
        Value: X;
        Next: Node;
    end;
public
    // Stack members.
end;

Node has only two members. For more complex types, it's better to move the nested declaration out from the parent type declaration:

Stack = sealed class[X]
private
    Node = sealed class;
public
    // Stack members.
end;

Stack[X].Node = sealed class
public
    Value: X;
    Next: Node;
end;

Note that, no matter whether Stack is declared public or internal, Node is a private nested class, since the accesibility of the class stub has precedence. Any type modifiers, as sealed in our example, must be repeated both in the stub and in the later declaration.

Forward declarations for inner types are only available for nested classes, records and interfaces. On the contrary, enumerations and delegates are always declared inside their outer types:

BinaryTree = class[X(IComparable[X])]
protected
    TreeNode = sealed class;
public
    Visitor = method(Obj: X; Level: Integer);

    method Visit(Action: Visitor);
    // ...
end;

Implementing a nested type

Nested classes and records with executable members must have their own implementation section.

implementation for BinaryTree[X].TreeNode is

    constructor(Value: X);
    begin
        Self.Value := Value;
    end;

This implementation may be an inline implementation, as in this example:

LinkedList = class[X](ICollection[X])
protected
    Node = class
    public
        constructor(Value: X);
        property Value: X; readonly;
        property Next: Node;
    implementation

        constructor(Value: X);
        begin
            Self.Value := Value;
        end;

    end;
public
    method Add(Value: X);
    method Clear;
    // ...
end;

See also

The Freya Programming Language
Type declarations
Class declarations
Record declarations