SIMPOL Documentation

Value Types, Reference Types, and Type Tags

There are two conceptually different data types within SIMPOL, value types and reference types. Value types are, as the name implies, associated with values. These types are similar to the scalar types in other languages. Variables that are declared as: boolean, integer, number, or string are value types. When a variable is declared to be of one of these types and a value is then assigned to the variable, an object is created and associated with the variable and the value of the object is set to the value that is being assigned. Values can be assigned to variables of this type using the = operator.

Reference types are more complicated, since they do not merely contain a single value but represent more sophisticated objects. An object is assigned to a variable of this type using the =@ or the @= operator. This is similar to the construct common in various BASIC dialects including Microsoft Visual Basic and Superbase Basic Language that uses the SET keyword and the equals symbol.

There are a couple of important points to realize when working with reference types. First, even value type variables can be used as reference variables. Second, more than one variable can refer to the same object. See the example below:

function main()
  integer i
  integer j

  i = 1
  j =@ i
  i = 3
end function j

The statement i = 1 assigns to the integer object referred to by i the value of the integer constant 1, whereas j =@ i causes both i and j to refer to the same integer object, so that when a value is assigned to i it is setting the value of the object to which j refers. This applies to any reference type and can provide a great degree of flexibility when writing programs. As an example, a database record is represented by a single variable and a second variable can easily point to the same database record while potential modifications are happening to the first variable. If those changes are occurring to the actual object, then the second variable will also be aware of the changes. If the first variable is then reassigned to another object, the second variable will still refer to the original object.

So what are type tags and why would anyone want to use them? Earlier in the chapter we discussed the usefulness of having a variable be able to refer to objects of more than one type. In a strongly typed language like SIMPOL, this normally wouldn't be possible. The type object has two functions that are accessed by the convention type(*) and type(=). The first of the two is used to declare a variable that can contain a reference to any type. The second is used to declare a variable that can contain a reference to any value type. That sounds pretty useful, we can now declare a variable that can refer to any type, so why use anything else? Mainly because it is considerably more expensive to handle a variable that can hold a reference to any type and also because it makes it very difficult to find errors in the program.

In line with that kind of thinking, type tags (you knew we would get back to them sooner or later) were introduced to allow the declaration of variables that could refer to only a limited set of types. So how does this work? Imagine we are creating a group of types to represent form controls. We may create a text box object, a check box, a command button, and so on. We might choose to assign a tag to each of the types called FormControl. By doing that we can then use the type object to create a variable that can refer to any type that is tagged as FormControl but not any other type, so if there is a mistake in the program it will still break at the right point for the right reason. The way we declare the variable looks like this: type(FormControl) fc. So how do we actually assign the tag? Look at the following example:

type tTextBox (FormControl, EditControl)
  string Text embed
  boolean Enabled embed
  type(FormControl) next
end type

type tCheckBox (FormControl)
  string Caption embed
  boolean Enabled embed
  boolean Selected embed
  type(FormControl) next
end type

In the preceding example the tTextBox type is tagged as being both a FormControl and an EditControl. The tCheckBox type is only tagged as a FormControl. A variable that has been declared to be of type tag FormControl can hold a reference to either of these two types. Before we leave type tags behind us, it is important to point out that a local variable can be declared either inside the function or else in the parameter list of the function.