As mentioned above, it is possible to specify a term class as the type of a slot of some other object. For example, we might declare
:- class colored_rectangle = [ public origin:point, public size:size, public color:rgb_color].
This will store an rgb_color
object (i.e., a color/3
term) in
the color
slot of each colored_rectangle
object.
Unfortunately, though, SICStus Objects cannot tell what is the best
way to store a term object, and therefore it stores it the same way it
stores a slot declared to be of term
type: using the Prolog
database. This has all the efficiency disadvantages of term
slots. In this
case, however, we know that all that really needs to be saved in order
to save an rgb_color
object is the three arguments. We also know
that each of these arguments is a floating point number, and because
precision isn't terribly critical in representating colors, each of
these numbers can be stored as a float
, rather than a double
.
In effect, we know that the essence of a rgb_color
object is
these three numbers; if we have them, we can easily construct the
color/3
term. If we provide this information in the declaration
of the rgb_color
class, SICStus Objects can store instances of
the rgb_color
class as 3 separate floats, rather than as a term,
significantly improving the performance of creating or destroying a
colored_rectangle
object, as well as accessing or modifying its
color
slot.
The essence of a term class is specified with the following form of
class
declaration:
:- class ClassName = term(Term, Constraint, Essence).
where Essence is of the form
[Name1:Type1=i[Variable1], Name2:Type2=i[Variable2], ...]
and each Name is a distinct atom naming a slot, each
Type is a slot type as specified in obj-scl-slt, and each
Variable is an unbound variable appering in Term.
Providing a term essence not only makes storage of terms in ordinary
object slots more efficient, it also gives a name to each
“essential” slot of the term class. This allows you to use
fetch_slot
to fetch the slots of this class.
To extend our rgb_color
example, we might introduce the rgb_color
class with this declaration:
:- class rgb_color = term(color(Red,Green,Blue), (float(Red), Red >= 0.0, Red =< 1.0, float(Green), Green >= 0.0, Green =< 1.0, float(Blue), Blue >= 0.0, Blue =< 1.0), [red:float=Red, green:float=Green, blue:float=Blue]).
This declaration defines the rgb_color
class exactly as the
example declaration of the previous section: every color/3
term
whose arguments are all floating point numbers between 0.0 and 1.0
inclusive are instances of rgb_color
. The difference is that with
this declaration, ordinary classes that have slots of type
rgb_color
, such as the colored_rectangle
example above,
will be stored more efficiently, and their rgb_color
slots will be accessed and modified much more efficiently.
Also, it will be possible to use fetch_slot(red, Red)
in the
methods of the rgb_color
class to fetch to red component of the
message recipient, and similarly for green
and blue
.