Contents | Prev | Next The T Language Specification
Spring 2005

CHAPTER 2

Types, Values, and Variables


The T programming language is a strongly typed language, which means that every variable and every expression has a type that is known at compile time. Types limit the values that a variable can hold or that an expression can produce, limit the operations supported on those values, and determine the meaning of the operations. Strong typing helps detect errors at compile time.

The types of the T programming language are divided into two categories: primitive types and reference types. There is only one primitive type, the integer type int. The reference types are class types and array types. There is also a special null type. An object is a dynamically created instance of a class type or a dynamically created array. The values of a reference type are references to objects. All objects, including arrays, support the methods of class Object. Names of types are used in declarations, class instance creation expressions and array creation expressions.

A variable is a storage location. A variable of a primitive type always holds a value of that exact type. A variable of a class type T can hold a null reference or a reference to an instance of class T or of any class that is a subclass of T. If T is a primitive type, then a variable of type "array of T" can hold a null reference or a reference to any array of type "array of T"; if T is a reference type, then a variable of type "array of T" can hold a null reference or a reference to any array of type "array of S" such that type S is assignable to type T. A variable of type Object can hold a null reference or a reference to any object, whether class or array.

2.1 The Kinds of Types and Values

There are two kinds of types in the T programming language: primitive types and reference types. There are, correspondingly, two kinds of data values that can be stored in variables, passed as arguments, returned by methods, and operated on: primitive values and reference values.



Type:

    PrimitiveType

    ReferenceType



There is also a special null type, the type of the expression null, which has no name. Because the null type has no name, it is impossible to declare a variable of the null type. The null reference is the only possible value of an expression of null type. The null reference can always be converted to any reference type. In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.

2.2 Primitive Types and Values

A primitive type is predefined by the T programming language and named by its reserved keyword. There is only one of these:

PrimitiveType:

    int

Primitive values do not share state with other primitive values. A variable whose type is a primitive type always holds a primitive value of that same type. The value of a variable of primitive type can be changed only by assignment operations on that variable.

2.2.1 Integer Values

The values of the integer type are integers from -2147483648 to 2147483647, inclusive.

2.2.2 Integer Operations

The T programming language provides a number of operators that act on integer values and all result in a value of type int:

The built-in integer operators do not indicate overflow or underflow in any way.

2.3 Reference Types and Values

There are two kinds of reference types: class types and array types.



ReferenceType:

    ClassType

    ArrayType



ClassType:

    TypeName



ArrayType:

    Type [ ]



The sample code:

class Point { int[] metrics; }

declares a class type Point, and uses an array type int[] (an array of int) to declare the field metrics of the class Point.

2.3.1 Objects

An object is a class instance or an array.

The reference values (often just references) may be pointers to these objects, or a special null reference, which refers to no object.

A class instance is explicitly created by a class instance creation expression. An array is explicitly created by an array creation expression.

A new array object is implicitly created when an array initializer expression is evaluated; this can occur when a class is initialized, when a new instance of a class is created, or when a main block variable declaration statement is executed.

The operators on references to objects are:

There may be many references to the same object. Most objects have a state, stored in the fields of objects that are instances of classes or in the variables that are the components of an array object. If two variables contain references to the same object, the state of the object can be modified using one variable's reference to the object, and then the altered state can be observed through the reference in the other variable.

2.3.2 The Class Object

The class Object is a superclass of all other classes. A variable of type Object can hold a reference to any object, whether it is an instance of a class or an array. All class and array types inherit the only method of class Object, which is summarized here:

int equals(Object obj) { . . . }

The equals method defined by class Object returns 1 if the two references refer to the same object and 0 otherwise. This method can be overriden in subclasses to define a notion of object equality, which is based on value, not reference, comparison.

The Object class also defines a default destructor:

~Object() { . . . }

As Object is a superclass of every class, every time a class instance is deleted this destructor is ultimately called.

2.3.3 When Reference Types Are the Same

Two reference types are the same type if:

2.4 Where Types Are Used

Types are used in declarations, in class instance creation expressions, and in array creation expressions.

2.5 Variables

A variable is a storage location and has an associated type, sometimes called its compile-time type, that is, either a primitive type or a reference type. A variable's value can be changed by an assignment and a variable may only be assigned a value that is assignment compatible with its type.

Compatibility of the value of a variable with its type is guaranteed by the design of the T programming language except in the case where an object has been deleted (in which case the value of the variable does not have a defined type). Otherwise, default values are compatible and all variable assignments are checked for assignment compatibility at compile time, run time, or both (reference types).

2.5.1 Variables of Primitive Type

A variable of a primitive type always holds a value of that exact primitive type.

2.5.2 Variables of Reference Type

A variable of reference type can hold either of the following:

2.5.3 Kinds of Variables

There are five kinds of variables:

  1. An instance variable is a field declared within a class declaration. If a class T has a field a that is an instance variable, then a new instance variable a is created and initialized to a default value as part of each newly created object of class T or of any class that is a subclass of T. The instance variable effectively ceases to exist when the object of which it is a field has been destroyed (deleted).
  2. Array components are unnamed variables that are created and initialized to default values whenever a new object that is an array is created. The array components effectively cease to exist when the array is no longer referenced.
  3. Method parameters name argument values passed to a method. For every parameter declared in a method declaration, a new parameter variable is created each time that method is invoked. The new variable is initialized with the corresponding argument value from the method invocation. The method parameter effectively ceases to exist when the execution of the body of the method is complete.
  4. Constructor parameters name argument values passed to a constructor. For every parameter declared in a constructor declaration, a new parameter variable is created each time a class instance creation expression or explicit constructor invocation invokes that constructor. The new variable is initialized with the corresponding argument value from the creation expression or constructor invocation. The constructor parameter effectively ceases to exist when the execution of the body of the constructor is complete.
  5. Main block variables are declared by variable declaration statements within the main block. Declaration statements are only supported at the outer level of the main block, not at inner blocks within the main block. Whenever the flow of control reaches the variable declaration statement, a new variable is created for each variable declared in the declaration statement.

2.5.4 Initial Values of Variables

Every variable in a program must have a value before its value is used:

2.5.5 Types and Classes

In the T programming language, every variable and every expression has a type that can be determined at compile time. The type may be a primitive type or a reference type. Reference types are introduced by type declarations, which include class declarations.

Every object belongs to some particular class: the class that was mentioned in the creation expression that produced the object. This class is called the class of the object. (Arrays also have a class, as described at the end of this section.) An object is said to be an instance of its class and of all superclasses of its class.

Sometimes a variable or expression is said to have a "run-time type". This refers to the class of the object referred to by the value of the variable or expression at run time, assuming that the value is not null.

The compile time type of a variable is always declared, and the compile time type of an expression can be deduced at compile time. The compile time type limits the possible values that the variable can hold or the expression can produce at run time. If a run-time value is a reference that is not null, it refers to an object or array that has a class, and that class will necessarily be compatible with the compile-time type.

Every array also has a class; this class is Array[component-type], where component-type can be either int or the name of some reference type. This class name is not a valid identifier, so conflict with any user-defined classes is impossible.


Contents | Prev | Next The T Language Specification
Spring 2005

Author(s): Tom Olson (§2.1-2.5)