The Freya Programming Language

Constant members

See also

Classes and records can declare literal constants as members, for a limited set of predefined data types.

Literal constant members

Literal constant members are very similar to read only fields. They must declared in one of these ways:

const constant-identifier = expression;
const constant-identifier : predefined-type = expression;

Allowed types include all numerical types, both integer and real, strings, characters, boolean and enumerations. You can also declare constant members with any reference type, but the only allowed value for them is the nil reference. When the type is not explicitly included, it is inferred from the initializer expression.

In both cases, the initializer must be a constant expression: it can only contain constant operands, such as literal constants and other constant members, either from the same type or any other accessible type. Circular references, however, are not allowed, neither direct nor indirect.

Behavior on version changes

The set of allowed types for literal constants members is practically limitted to those who support literal constants at the lexical level. If you want something similar to these constant members for other data types, you must use static read only fields:

Complex = class
public
    property Re, Im: Double;

    constructor(Re, Im: Double);

public
    static Zero: Complex = new Complex(0, 0); readonly;
    static Unit: Complex = new Complex(1, 0); readonly;
    static Imag: Complex = new Complex(0, 1); readonly;
    // Declaration order is significative in this example.
    static I   : Complex = Imag; readonly;
end;

However, constant members and static readonly fields behave differently on version changes. Let's suppose we declare a constant member T.C in the class library assembly A, to use it later in executable assembly B. The value for T.C is stored as a literal definition inside the metadata from A. When B is compiled, the Freya compiler pick ups that literal value from A's metadata and uses it to evaluate any reference to T.C at compiling time. All this means that any further change in T.C's definition won't be noticed by assembly B, unless we recompile it.

On the contrary, if T.C were a static read only field, its value will always be evaluated at runtime. Any change in assembly A's definition for T.C will be immediatly noticed by assembly B even if the latter is not recompiled.

See also

The Freya Programming Language
Type declarations
Type members
Fields
Constructors
Methods
User defined operators
Iterators
Properties
Events