ClassType (API documentation of hlt.language packages)
Date: 2013-01-30

hlt.language.design.types

## Class ClassType

- java.lang.Object
- - hlt.language.design.types.Type
  - - hlt.language.design.types.StaticType
    - - hlt.language.design.types.NamedType
      - - hlt.language.design.types.TypeTerm
        - - hlt.language.design.types.ClassType

- All Implemented Interfaces:
    Valuable, java.lang.Cloneable

      public class ClassType
      extends TypeTerm

  This is the type of object structures. It declares an interface (or member type signature) for a class of objects and the members comprising its structure. It holds information for compiling field access and update, and enables specifying an implementation for methods manipulating objects of this type.

  A class implementation uses the information declared in its interface. It is interpreted as follows: only non-method members - hereafter called fields - correspond to actual slots in an object structure that is an instance of the class and thus may be updated. On the other hand, all members (i.e., both fields and method members) are defined as global functions whose first argument stands for the object itself (that must be explicitly referred to as `this` everywhere). Our prototype syntax for a class definition is of the form:

            class <classname> { <interface> } [ { <implementation> } ]

  For example, one can declare a class to represent a simple counter as follows:

            class Counter
                {
                   value : int = 1;
                   method set : int -> Counter;
                }
                {
                   set (n : int) : Counter = (this.value = n);
                }

  The first block specifies the interface for the class type `Counter` defining two members: a field `value` of type `int` and a method `set` taking an argument of type `int` and returning a `Counter` object. It also specifies an initialization expression (`1`) for the `value` field. Specifying a field's initialization is optional - when missing, the field will be initialized to a null value of appropriate type: `0` for an `int`, `0.0` for a `real`, `false` for a `boolean`, `_` for `void`, and `null(T)` for any other type `T`. [NB: Strictly speaking, a field of type `void` is useless since it can only have the unique value of this type (i.e., `_`). Thus, a `void` field should arguably be disallowed. On the other hand, allowing it is not semantically unsound and may be tolerated for the sake of uniformity.]

  The second (optional) block of a class declaration defines its implementation. Thus, the implementation block for the `Counter` class defines the body of the `set` method.

  Note that a method's implementation can as well be given outside the class declaration as a function whose first argument's type is the class. For example, we could have defined the `set` method of the class `Counter` as:

            def set (x : Counter, n : int) : Counter = (x.value = n);

  On the other hand, although a field is also semantically a function whose first argument's type is a class, it may not be defined outside its class. Defining a declared field outside a class declaration causes an error. This is because the code of a field is always fixed and defined to return the value of an object's slot corresponding to the field. Note however that one may define a unary function whose argument is a class type outside this class when it is not a declared field for this class. It will be understood as a method for the class (even though it takes no extra argument and may be invoked in "dot notation" without parentheses as a field is) and thus act as a "static field" for the class. Of course field updates using dot notation will not be allowed on these pseudo fields. However, they (like any global variable) may be (re)set using a global (re)definition at the top level, or a nested global assignment.

  Note also that a field may be functional without being a method - the essential difference being that a field is part of the structure of every object instance of a class and thus may be updated within an object instance, while a method is common to all instances of a class and may not be updated within a particular instance, but only globally for all the class' instances.

  Thus, every time a `Counter` object is created with `new` or `static`, as in, for example:

            c = new Counter;

  the value `1` will be used to initialize the slot that corresponds to the location of the `value` field. Then, field and method invocation can be done using the familiar "dot notation"; e.g.:

            c.set(c.value+2);
            write(c.value);

  This will set `c`'s `value` field to `3` and print out this value. This code is exactly equivalent to:

            set(c,value(c)+2);
            write(value(c));

  Indeed, field and method invocation simply amounts to functional application. This scheme offers the advantage that an object's fields and methods may be manipulated as functions (i.e., as first-class citizens) and no additional setup is needed for type-checking and/or type inference when it comes to objects.

  Incidentally, some or all type information may be omitted while specifying a class's implementation (though not its interface) as long as non-ambiguous types may be inferred. Thus, the class `Counter` above could be defined simply as:

            class Counter
                {
                   value : int = 1;
                   method set : int -> Counter;
                }
                {
                   set (n) = (this.value = n);
                }

  Declaring a class type and defining its implementation causes the following:

  - the name of the class is entered with a new type for it in the type table in `_tables` (an object comprising symbol tables, of type `Tables`), where its type definition associates it with a `ClassType` whose class structure is encapsulated by an object of type `ClassInfo` where code entries for all its members' types are recorded;

  - each field of a distinct type is assigned an offset in an array of slots (per sort);

  - each method and field expression is name-sanitized, type-checked, and sort-sanitized after closing it into an abstraction taking `'this'` as first argument;

  - each method definition is then compiled into a global definition, and each field is compiled into a global function corresponding to accessing its value from the appropriate offset;

  - finally, each field's initialization expression is compiled and recorded for it into the `ClassType` to be used at object creation time. An object may be created at run-time (using the `new` operator followed by a class name).

- - ### Field Summary

    - ### Fields inherited from class hlt.language.design.types.Type

      `ARRAY, BAG, BOOLEAN, BOXABLE, CHAR, CLASS, COLLECTION, CONSTANT, DEFINED, FUNCTION, INT, INT_RANGE, INT_SORT, LIST, NAMED_TUPLE, OBJECT_SORT, PARAMETER, REAL, REAL_RANGE, REAL_SORT, SET, STRING, TUPLE, VOID, VOID_SORT`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `ClassType(Tables tables, java.lang.String name)`
    `ClassType(Tables tables, java.lang.String name, java.util.AbstractList arguments)`
    `ClassType(Tables tables, java.lang.String name, Type[] arguments, ClassInfo classInfo)`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `bindArguments()`
    `ClassInfo` | `classInfo()`
    `ClassType` | `declareMembers(java.util.AbstractList members, java.util.AbstractList types, java.util.AbstractList fieldInits, java.util.AbstractList typeArguments)` Declares the members of this class type from the specified information and returns this class type.
    `DefinedEntry[]` | `fields()`
    `void` | `initialize(ObjectInstance object, Runtime init)` Initializes the fields of the specified object instance using the specified `Runtime`.
    `int` | `intFieldsCount()`
    `boolean` | `isDeclared()`
    `byte` | `kind()` This returns the value identifying what kind of type this is.
    `DefinedEntry[]` | `methods()`
    `int` | `nextOffset(byte sort)` Increments and returns the field offset in this class for the given sort.
    `int` | `objectFieldsCount()`
    `int` | `realFieldsCount()`
    `java.lang.String` | `toFullString()` N.B.: The following definition specifies only the default behavior for this method.
    `void` | `unbindArguments()`
    `void` | `undeclareClass(Tables tables)`

    - ### Methods inherited from class hlt.language.design.types.TypeTerm

      `argument, arguments, arity, checkOccurrence, copy, eqCode, flatten, getParameters, instantiate, isEqualTo, isEqualTo, isPolymorphic, numberOfTypeComponents, setArguments, setArguments, setTypeRefComponent, toString, typeRefComponent, unify, unify`

    - ### Methods inherited from class hlt.language.design.types.NamedType

      `name, setName`

    - ### Methods inherited from class hlt.language.design.types.Type

      `actualType, array, array, baseType, baseTypeRef, BOOLEAN, BOXED_BOOLEAN, BOXED_CHAR, BOXED_INT, BOXED_REAL, boxSort, CHAR, copy, curry, equals, findValue, getParameters, getValue, INT, is, isBag, isBoolean, isBoxedType, isChar, isCollection, isGlobalUnsafe, isInt, isList, isPrimitive, isReal, isSet, isString, isVoid, kindString, rank, REAL, resetNames, setBoxed, shadowType, sort, standardize, toQuantifiedString, toQuantifiedString, typeComponent, unwrapper, value, wrapper`

    - ### Methods inherited from class java.lang.Object

      `getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Constructor Detail

    - #### ClassType

          public ClassType(Tables tables,
                   java.lang.String name,
                   Type[] arguments,
                   ClassInfo classInfo)

    - #### ClassType

          public ClassType(Tables tables,
                   java.lang.String name)

    - #### ClassType

          public ClassType(Tables tables,
                   java.lang.String name,
                   java.util.AbstractList arguments)

  - ### Method Detail

    - #### kind

          public final byte kind()

      Description copied from class: `Type`
      This returns the value identifying what kind of type this is.
      Specified by:
        `kind` in class `Type`

    - #### classInfo

          public final ClassInfo classInfo()

    - #### isDeclared

          public final boolean isDeclared()

    - #### fields

          public final DefinedEntry[] fields()

    - #### methods

          public final DefinedEntry[] methods()

    - #### intFieldsCount

          public final int intFieldsCount()

    - #### realFieldsCount

          public final int realFieldsCount()

    - #### objectFieldsCount

          public final int objectFieldsCount()

    - #### nextOffset

          public final int nextOffset(byte sort)

      Increments and returns the field offset in this class for the given sort.

    - #### bindArguments

          public final void bindArguments()

    - #### unbindArguments

          public final void unbindArguments()

    - #### declareMembers

          public final ClassType declareMembers(java.util.AbstractList members,
                                 java.util.AbstractList types,
                                 java.util.AbstractList fieldInits,
                                 java.util.AbstractList typeArguments)
                                         throws ClassDeclarationException

      Declares the members of this class type from the specified information and returns this class type. If some members have duplicate signatures, a `ClassDeclarationException` is thrown and no type definition for the class or any of its member is taken into account. Note that the field offsets are not computed by, nor kept in, the class type itself but by, and in, the field's `DefinedEntry`. This is not only much more efficient to have the offset readily available there when compiling field accesses and updates, it is also necessary as these offsets can be safely computed only once the fields have been fully type-checked to know which of an object's sorted array to offset them in.
      Throws:
        `ClassDeclarationException`

    - #### undeclareClass

          public final void undeclareClass(Tables tables)

    - #### initialize

          public final void initialize(ObjectInstance object,
                        Runtime init)
                                throws ObjectInitializationException

      Initializes the fields of the specified object instance using the specified `Runtime`.
      Throws:
        `ObjectInitializationException`

    - #### toFullString

          public final java.lang.String toFullString()

      Description copied from class: `Type`

      N.B.: The following definition specifies only the default behavior for this method. Specific subclasses are generally expected to override this method.

      Overrides:
        `toFullString` in class `Type`