Class Value
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.
Performance
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