Most types are declared inside the scope of a namespace. However, types can also be declared inside class and record declarations, as nested types
There are two syntactic variants for declaring a nested type:
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;
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;
The Freya Programming Language
Type declarations
Class declarations
Record declarations