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 Value
s, 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 Value
s as
described below, but is not required to and it would be valid for it to treat Value
s 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 Value
s 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