Using SICStus Objects

One of the basic ideas of object-oriented programming is the encapsulation of data and procedures into objects. Each object belongs to exactly one class, and an object is referred to as an instance of its class. A class definition determines the following things for its objects:

All interaction with an object is by sending it messages. The command to send a message to an object has the form

     Object MessageOp Message

where Object is an object, MessageOp is one of the message operators (‘<<’, ‘>>’, or ‘<-’) and Message is a message defined for the object's class. Roughly speaking, the ‘>>’ message operator is used for extracting information from an object, ‘<<’ is for storing information into an object, and ‘<-’ is for any other sort of operation.

For example, using the point class defined in the next section, it would be possible to give the following command, which demonstrates all three message operators.

     | ?- create(point, PointObj),
          PointObj >> x(InitX),
          PointObj >> y(InitY),
          PointObj << x(2.71828),
          PointObj << y(3.14159),
          PointObj <- print(user_output),
     PointObj = point(23461854),
     InitX = 1.0,
     InitY = 2.0

First it binds the variable PointObj to a newly created point object. Then, the two get messages (sent with the ‘>>’ operator) fetch the initial values of the point's x and y slots, binding the variables InitX and InitY to these values. Next, the two put messages (sent with the ‘<<’ operator) assign new values to the object's x and y slots. Finally, the send message (sent with the ‘<-’ operator) instructs the point object to print itself to the user_output stream, followed by a newline. Following the goal, we see the point has been printed in a suitable form. Following this, the values of PointObj, InitX, and InitY are printed as usual for goals entered at the top-level prompt.

Because this goal is issued at the top-level prompt, the values of the variables PointObj, InitX and InitY are not retained after the command is executed and their values are displayed, as with any goal issued at the top-level prompt. However, the point object still exists, and it retains the changes made to its slots. Hence, objects, like clauses asserted to the Prolog database, are more persistent than Prolog variables.

Another basic idea of object-oriented programming is the notion of inheritance. Rather than defining each class separately, a new class can inherit the properties of a more general superclass. Or, it can be further specialized by defining a new subclass, which inherits its properties. (C++ uses the phrase “base class” where we use “superclass.” It also uses “derived class” where we use “subclass.”)

SICStus Objects uses term expansion to translate object-oriented programs into ordinary Prolog. (This is the same technique that Prolog uses for its DCG grammar rules.) As much as possible is done at compile time. Class definitions are used to generate Prolog clauses that implement the class's methods. Message commands are translated into calls to those Prolog clauses. And, inheritance is resolved at translation time.

SICStus Objects consists of two modules, obj_decl and objects. The obj_decl module is used at compile time to translate the object-oriented features of SICStus Objects. Any file that defines classes or sends messages should include the command

     :- load_files(library(obj_decl),
                   [when(compile_time), if(changed)]).

The objects module provides runtime support for SICStus Objects programs. A file that sends messages or asks questions about what classes are defined or to what class an object belongs should include the command:

     :- use_module(library(objects)).

You will probably include both in most files that define and use classes.

Please note: A file that loads library(obj_decl) currently cannot recursively load another file that loads library(obj_decl), because that would confuse the internal database being used by the package.

If you use the foreign resource linker, splfr, on a Prolog file that uses the objects package, you must pass it the --objects option. This will make splfr understand the package's syntax extensions.

Send feedback on this subject.