Values
Subclasses of frost.core.Value
are called "value classes" or "values".
While most objects are passed by reference, values are passed by value. Values do not have a
distinct identity and may not be compared using the ==
or !==
operator. Values are "plain old
data" objects; they do not have a pointer to their class (in C++ parlance, they have no vtable) nor
any other hidden header fields. Values are stack allocated and are not subject to refcounting.
Value classes may not be subclassed.
Values are essentially equivalent to immutable stack allocated C struct
s.
Performance Considerations
Value objects allow for many optimizations; Frost would be unacceptably slow if Int
were a regular
class instead of a value - even calculating 1 + 1
would involve multiple heap allocations.
Fortunately, this is not the case, and after optimization, math in Frost compiles down to the same
basic arithmetic instructions that it does in languages like C.
However, there are still some pitfalls to be aware of. Casting a value type to an Object
requires
Frost to convert it to a full-fledged refcounted object with an object header. This "wrapping" is
handled automatically, as is unwrapping if the object is cast back to an object type, but it can
incur a significant performance impact.
Casting a value type to a nullable value type (such as a cast from Int64
to Int64?
) is much
cheaper than converting it all the way to Object
. The nullable version of a value type is only a
single byte longer than the normal non-nullable version and is still stack allocated.