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