Class Value

    └ Immutable
         └ Object


Represents objects which may be passed by value instead of by reference. Value objects may not be declared @extendable, may not be compared using the == / !== operators, and as Value is a subclass of Immutable, are naturally immutable as well. "Tricking" Frost into using the == / !== operators on Values, such as in:

def i1:Object := 5 -- Int is a subclass of Value
def i2:Object := 5
Console.printLine(i1 == i2)

gives undefined results. This could legally print either true or false, and the result may differ from run to run of the same code.


These restrictions permit the compiler to make several important optimizations around Value objects. These are implementation details - the Frost compiler currently treats Values as described below, but is not required to and it would be valid for it to treat Values just as any other object.

Values are not allocated on the heap and do not need to be reference counted. Because they cannot be subclassed, they do not need to store a pointer to their class the way most objects do. A Value object is therefore just a simple structure consisting of its fields, exactly like a struct in the C programming language, with the same performance characteristics.

Converting a Value to an ordinary class type (e.g. def o:Object := 5) requires it to be "wrapped" in an actual Object instance. This wrapping is handled automatically by the compiler, but does carry a performance penalty due to the memory allocation and reference counting it entails.

Converting a Value to its corresponding nullable type (e.g. def i:Int? := 5) is much cheaper than wrapping it. A nullable Value is internally represented using only a single extra Bit to distinguish null from non-null values. Nullable Values are still stack allocated and passed by value with no reference counting.

Again, the compiler handles all of these details automatically. It is only explained here so that the performance implications are clear.

Source Code:
View Source
Inherited Fields: