The Sway Reference Manual/Objects

In the Sway world, an object is a simple a collection of related variables. You've already been exposed to objects, although you may not have realized it. When you created a variable, you modified the environment, which is an object. When you defined a function, you created an object. To view an object, we use the predefined function pp or ppObject[1]. Evaluating the code:

   function square(x)
       {
       x * x;
       }
   
   ppObject(square);

yields the following output:

   <FUNCTION 3059>:
       context: <OBJECT 677>
       prior: :null
       filter: :null
       parameters: (x)
       code: { x * x; }
       name: square

We see that the square function is made up of six fields[2]. These fields are: context, prior, filter, parameters, code, and name.

Usually, an object lets you look at its individual components. For example:

   println("square's parameters are: ",square . parameters);

yields:

   square's parameters are: (x)
   

We use the function '.' (usually called the dot operator) to extract the fields of an object.

It is easy to create your own objects. First you must make a constructor. A constructor is just a function that returns this. Suppose you want a constructor to create an object with fields name and age. Here is one possibility:

   function person()
       {
       var name;
       var age;
       
       this;
       }

We can create an object simply by calling the constructor:

   var p = person();

The variable p now points to the person object and we can use p and the dot operator to set the fields of the person object:

   p . name = "Boris";
   p . age = 33;
   inspect(p . name);

Evaluating this code yields the following output:

   p . name is Boris

It is often convenient to give initial values to the fields of an object. Here is another version of person that allows us to do just that when we create the object:

   function person(name,age)
       {
       this;
       }
       
   var p = person("Boris",33);
       
   inspect(p . name);

The output is the same:

   p . name is Boris

In general, if a field is to be initialized when the object is constructed, make that field a formal parameter. If not, make the field a locally declared variable.

Adding Methods

edit

Objects can have methods[3] as well. Here's a version of the person constructor that has a birthday method.

   function person(name,age)
       {
       function birthday()
           {
           println("Happy Birthday, ",name,"!");
           age = age + 1;
           }
       this;
       }
       
   var p = person("Boris",33);
   p . birthday();
   inspect(p . age);

The output of this code is:

   Happy Birthday, Boris!
   p . age is 34

In summary, one turns a function into a constructor by making

   this;

or

   return this;

the last line of a function. The local variables, including formal parameters, become the fields of the function while any local functions serve as methods.

Objects and Types

edit

If you were to ask an object, "What are you?", it would respond, "I am an object!". The type function is used to ask such questions:

   var p = person("betty",19);
   inspect(type(p));

yields:

   type(p) is :OBJECT

While this is useful at times, often we would like to know what kind of object the object is. For example, we might like to know whether or not p is a person object. One way to do this is to ask the constructor of the object if it is the person function. Luckily, all objects carry along a pointer to the function that constructed them:

   var p = person("betty",19);
   inspect(p . constructor . name);

yields:

   p . constructor . name is person

So, to ask if p is a person, we would use the expression

   if (p . constructor . name == :person) ...

Since this construct is rather wordy, there is a simple function, named is, that you can use instead:

   if (p is :person) ...

The is function works for non-objects too. All of the following expressions are true:

   3 is :INTEGER
   3.4 is :REAL
   "hello" is :STRING
   :blue is :SYMBOL
   list(1,2,3) is :LIST
   array("a","b","c") is :ARRAY
   person("betty",19) is :OBJECT
   this is :OBJECT

The is function also works for variables bound to values as well.

A formal view of object-orientation

edit

Sway is a fully-featured object-oriented language. What does that mean exactly? Well, to begin with, a programming language is considered object-oriented if it has these three features:

  1. encapsulation
  2. inheritance
  3. polymorphism

Encapsulation in this sense means that a programmer can bundle data and methods into a single entity. We've seen that a Sway function can have local variables and local functions. So, if we consider local variables (including the formal parameters) as data and local functions as methods, we see that Sway can encapsulate in the object-oriented sense.

Inheritance is the ability to use the data and methods of one kind of object by another as if they were defined in the other object to begin with.

Polymorphism means that an object that inherits appears to be both kinds of object, the kind of object it is itself and the kind of object from which it inherits. We will learn more about inheritance and polymorphism in a later chapter.

Using the objects library

edit

If you include the objects library, you can add toString methods to your objects. Then when you display the objects, the toString method is called to help generate the output.

Footnotes

edit
  1. The pp in the function names stands for pretty print which means to print out something so it is 'pretty looking'.
  2. Some people use the term component or instance variable instead of field. Also, if you try this, you may see different numbers than 3059 and 677.
  3. A method is just another name for a local function.


Arrays and Lists · Inheritance