Sather - A Language Manual - Built-in classes

[back] [Abstract] [Copyright Notice] [Contents] [next]

# Sather - A Language Manual - Chapter 12
Built-in classes

This section provides a short description of classes that are a part of every Sather implementation and which may not be modified. The detailed semantics and precise interface are specified in the class library documentation.

## 12.1 Fundamental Classes

There are a handful of classes that are specially recognized by the compiler and are implicitly and explicitly used in most Sather code.

### 12.1.1 $OB

`'$OB'` is automatically a supertype of every type. Variables declared to be of this type may hold any object. It has no features.

### 12.1.2 Array support

Sather objects may have an array portion, which is specified by including either the primitive reference of value array

- `'AREF{T}'` is a reference array class. Any reference class which includes it obtains an array of elements of type `T` in addition to any attributes it has defined. In such classes, `new` has a single integer argument that specifies the size of the array portion. It defines routines and iters named: '`asize`', '`aget`', '`aset`', '`aclear`', '`acopy`', '`aelt!`', '`aset!`', and '`aind!`'. Array indices start at zero.

- '`ARRAY{T}`' includes from '`AREF`' and defines general purpose array objects. They may be directly constructed by array creation expressions.

- '`AVAL{T}`' is the immutable class analog of '`AREF`'. Classes which include '`AVAL`' must define `asize` as an integer constant which determines the size of the array portion.

## 12.2 Tuples

Tuples are not really a fundamental class, but are commonly used for a very fundamental purpose - multiple return values.

'`TUP`' names a set of parameterized immutable types called tuples, one for each number of parameters. Each has as many attributes as parameters and they are named '`t1`', '`t2`', etc. Each is declared by the type of the corresponding parameter (e.g. '`TUP{INT,FLT}`' has attributes '`t1:INT`' and '`t2:FLT`'). It defines '`create`' with an argument corresponding to each attribute.

## 12.3 The `SYS` Class

`SYS` defines a number of routines for accessing system information:

Operation in the `SYS` class

Routine
  Description

`is_eq(ob1, ob2:$OB):BOOL`
  Tests two objects for equality. If the arguments are of different type, it returns '`false`'. If both objects are immutable, this is a recursive test on the arguments' attributes. If they are reference types, it returns '`true`' if the arguments are the same object. It is a fatal error to call with external, closure, or void reference arguments.

`is_lt(ob1, ob2:$OB):BOOL`
  Defines an arbitrary total order on objects. This never returns true if '`is_eq`' would return true with the same arguments. It is a fatal error to call with external, closure, or void reference arguments.

`hash(ob:$OB):INT`
  Defines an arbitrary hash function. For reference arguments, this is a hash of the pointer; for immutable types, a recursive hash of all attributes. Hash values for two objects are guaranteed to be identical when 'is_eq' would return true, but the converse is not true.

`type(ob:$OB):INT`
  Returns the concrete type of an object encoded as an '`INT`'.

`str_for_type(i:INT):STR`
  Returns a string representation associated with the integer. Useful for debugging in combination with '`type`' above.

`destroy(ob:$OB)`
  Explicitly deallocates an object. Sather is garbage collected and casual use of '`destroy`' is discouraged. Sather implementations provide a way of detecting accesses to destroyed objects (a fatal error).

## 12.4 Object Finalization: `$FINALIZE`

`$FINALIZE` defines the single routine `finalize`. Any class whose objects need to perform special operations before they are garbage collected should subtype from `$FINALIZE`. The `finalize` routine will be called once on such objects before the program terminates. This may happen at any time, even concurrently with other code, and no guarantee is made about the order of finalization of objects which refer to each other. Finalization will only occur once, even if new references are created to the object during finalization. Because few guarantees can be made about the environment in which finalization occurs, finalization is considered dangerous and should only be used in the rare cases that conventional coding will not suffice.

## 12.5 Basic Classes and Literal Forms

The basic Sather classes such as integers and booleans are not treated specially by the compiler. However, they do have language support in the form of convenient literal forms that permit easy specification of values. These literal forms all have a concrete type derived from the syntax; typing of literals is not dependent on context. Each of these basic classes also has a default void initial value.

Type
  Description

`BOOL`
  Initial Value: `false` - Immutable objects which represent boolean values.

`CHAR`
  Initial Value: `'\0'` - Immutable objects which represent characters. The number of bits in a '`CHAR`' object is less than or equal to the number in an '`INT`' object.

`STR`
  Initial Value: `""` (= `void`) - Reference objects which represent strings for characters. '`void`' is a representation for the null string.

`INT`
  Initial Value: `0` - Immutable objects which represent efficient integers. The size is defined by the implementation but must be at least 32 bits. Bit operations are supported in addition to numerical operations.

`INTI`
  Initial Value: `0i` - Reference objects which represent infinite precision integers.

`FLT`
  Initial Value: `0.0` - Immutable objects which represent single precision floating point values as defined by the IEEE-754-1985 standard.

`FLTD`
  Initial Value: `0.0d` - Immutable objects for double precision floating point values.

### 12.5.1 Booleans and the BOOL class

Examples:

    a:BOOL := true;
    b ::= false;
    c:BOOL := a.and(b);
    if a.and(b).or(d) then
    end;

`BOOL` objects represent boolean values (See also Conditional Execution, section 2.5). The two possible values are represented by the boolean literal expressions: '`true`' and '`false`'. Boolean objects support the standard logical operations. Note that these logical operations are evaluated in the standard way, and not short-circuited. The Sather expressions "and" and "or" provide a short circuit logical operations.

    if b.has_value and b.get_value > 3 then
       -- The short circuit and will only evaluate b.get_value
       -- if b.has_value is true
    end;

### 12.5.2 Characters and the CHAR class

Examples:

    c:CHAR := 'a';
    new_line:CHAR := '\n';
    code_16:CHAR := '\016';

`CHAR` objects represent characters. Character literal expressions begin and end with single quote marks. These may enclose either any single ISO-Latin-1 printing character except single quote or backslash or an escape code starting with a backslash.

- `'\a'` is an alert such as a bell

- `'\b'` is the backspace character

- `'\f'` is the form feed character

- `'\n'` is the newline character

- `'\r'` is the carriage return character

- `'\t'` is the horizontal tab character

- `'\v'` is the vertical tab character

- `'\\'` is the backslash character

- `'\''` is the single quote character

- `'\"'` is the double quote character

A backslash followed by one or more octal digits represents the character whose octal representation is given. A backslash followed by any other character is that character. The mapping of escape codes to other characters is defined by the Sather implementation.

### 12.5.3 The string class, STR

Examples:

    s:STR := "a string literal"
    d:STR := "concat" "enation\015"
             -- d  is  "concatenation\015"

`STR` objects represent strings. String literal expressions begin and end with double quote marks. A backslash starts an escape sequence as with character literals. All successive octal digits following a backslash are taken to define a single character. Individual string literals may not extend beyond a single line, but successive string literals are concated together. Thus, a break in a string literal can also be used to force the end of an octal encoded character. For example: `"\0367"` is a one character string, while `"\03""67"` is a three character string. Such segments may be separated by comments and whitespace.

### 12.5.4 Integers and the INT class

Examples:

    a:INT := 14;
    b:INT := -4532;
    c:INT := 39_8322_983_298;
    binary:INT := 0b101011;
    bin:INT := -0b_101010_1010;
    octal:ITN := 0o37323;
    hex_num:INT:= 0x_ea_75_67;

`INT` objects represent machine integers. Integer literals can be represented in four bases: binary is base 2, octal is base 8, decimal is base 10 and hexadecimal is base 16. These are indicated by the prefixes: '`0b`', '`0o`', nothing, and '`0x`' respectively. Underscores may be used within integer literals to improve readability and are ignored. `INT` literals are only legal if they are in the representable range of the Sather implementation, which is at least 32 bits.

Underscores may be used to separate the digits of an integer to improve readability - this may be particularly useful for very long binary numbers.

### 12.5.5 Infinite precision integers and the INTI class

Examples:

    b:INTI := -4532i;
    infinite_hex:INTI := 0o373254i;

Infinite precision integers are are implemetned by the INTI class and supported by a literal form which is essentially the same as that of integers, but with a trailing 'i'. All the standard arithmetic operations are defined on infinite precision integers.

### 12.5.6 Floating point numbers: the FLT and FLTD classes

Examples:

    f:FLT := 12.34;
    fd:FLTD := 3.498_239e-8d;

Syntax:

flt_literal_expression [`-`] decimal_int `.` decimal_int [`e` [`-`] decimal_int] [ `d` ]

`FLT` and `FLTD` objects represent floating point numbers according to the single and double representations defined by the IEEE-754-1985 standard). A floating point literal is of type `FLT` unless suffixed by 'd' designating a `FLTD` literal. The optional '`e`' portion is used to specify a power of 10 by which to multiply the decimal value. Underscores may be used within floating point literals to improve readability and are ignored. Literal values are only legal if they are within the range specified by the IEEE standard.

Sather does not do implicit type coercions (such as promoting an integer to floating point when used in a floating point context.) Types must instead be promoted explicitly by the programmer. This avoids a number of portability and precision issues (for example, when an integer can't be represented by the floating point representation.

The following two expressions are equivalent. In the first, the '`d`' is a literal suffix denoting the type. In the second, '`3.14`' is the literal and '`.fltd`' is an explicit conversion.

    3.14d      -- A double precision literal
    3.14.fltd  -- Single, but converted

## 12.6 Library Conventions

In addition to '`create`', there are a number of other naming conventions:

- Classes which are related should reflect this in their names. For example, there are many examples in the library of an abstraction, classes implementing the abstraction, and code testing implementations of the abstraction. For example, in the standard library the set abstraction is named `$SET, H_SET` is a hash table implementation, and the test code is `TEST_SET`.

- Some classes implement an immutable, 'mathematical' abstraction (eg. integers), and others implement mutable "object" abstractions that can be modified in place (eg. arrays). For most objects, the mutable, object semantics are natural and efficient. However, for classes such as sets, the semantics may be different from those of the traditional mathematical set entities.

- Classes with immutable semantics are given their 'mathematical' names: STR, `VEC`, `$SET`. When separate abstractions exist to handle value and reference semantics, the method `value` will be provided in the reference version to provide an immutable snapshop of the reference class.

- Conversions from a type `FOO` to a type `BAR` occur in two ways: by defining an appropriate '`create(f:FOO):BAR`' routine in `BAR` as seen above, or be defining a routine '`bar:BAR`' in `FOO`. For example, in the standard library conversion of a `FLT` to a `FLTD` is done by calling the routine '`fltd:FLTD`' defined in `FLT`.

- Methods which return a `BOOL` (called predicates), usually have the prefix '`is_`'. For example, '`is_prime`' tests integers for primality.

- Abstract classes that require a single method should be named after that method. For example, subtypes of `$HASH` define the method '`hash`'.

- If there is a single iterator in a container class which returns all of the items, it should be named '`elt!`'. If there is a single iterator which sets the items, it should be named '`set!`'. In general, iterators should have singular ('`elt!`') rather than plural ('`elts!`') names if the choice is arbitrary.

### 12.6.1 Object Identity

Many languages provide built-in pointer and structural equality and comparison. To preserve encapsulation, in Sather these operations must go through the class interface like every method. The '`=`' symbol is syntactic sugar for a call to '`is_eq`' (See also Operator expressions, section 7.2). '`is_eq:BOOL`' must be explicitly defined by the type of the left side for this syntax to be useful.

The `SYS` class (See The `SYS` Class, section 12.3) can be used to obtain equality based on pointer or structural notions of identity. This class also provides built-in mechanisms for comparison and hashing.

IS_EQ

Classes which define their own notion of equality should subtype from `$IS_EQ`. This class is a common parameter bound in container classes. In the standard library, we have

    abstract class $IS_EQ is
       is_eq(e:$OB):BOOL;
    end;

Many classes define a notion of equality which is different than pointer equality. For example, two `STR` strings may be equal although, in general, strings are not unique.

    class STR < $IS_EQ is ...
       is_eq(arg:$OB):BOOL is ... end;
       ...
    end; -- class STR.

Programmer defined hash functions and $HASH

Many container classes need to be able to compute hash values of their items. Just as with '`is_eq`', classes may subtype from `$HASH` to indicate that they know how to compute their own hash value. $HASH is defined in the library to be

    abstract class $HASH is
       hash:INT;
    end;

Objects that can be copied and $COPY

To preserve class encapsulation, Sather does not provide a built-in way to copy objects. By convention, objects are copied by a class-defined routine '`copy`', and classes which provide this should subtype from `$COPY`. $COPY is defined in the standard library.

    abstract class $COPY is
       copy:SAME;
    end;

### 12.6.2 Nil and void

Reference class variables can be declared without being allocated. Unassigned reference or abstract type variables have the `void` value, indicating the non-existence of an object. However, for immutable types this unassigned value is not distinguished from other legitimate values; for example, the `void` of type `INT` is the value zero.

It is often algorithmically convenient to have a sentinel value which has a special interpretation. For example, hash tables often distinguish empty table entries without a separate bit indicating that an entry is empty. Because `void` is a legitimate value for immutable types, `void` can't be used as this sentinel value. For this reason, classes may define a '`nil`' value to be used to represent the non-existence of an immutable object. Such classes subtype from `$NIL` and define the routines '`nil:SAME`' and `'is_nil: BOOL`'.

The '`nil`' value is generally a rarely used or illegal value. For `INT`, it is the most negative representable integer. For floating point types, it is `NaN`. '`is_nil`' is necessary because `NaN` is defined by `IEEE` to not be equal to itself.

    abstract class $NIL is
       nil:SAME;
       is_nil:BOOL;
    end; -- anstract class $NIL

[back] [Abstract] [Copyright Notice] [Contents] [next]

Sather - A Language Manual