# Types

The syntax for type definitions are similar for values, classes, and actors. Defining a value type is done using the `value` keyword as follows:

    value <name> [: <options>] {
        <members>
    }

The syntax above defines a value named `<name>`. `<members>` is a list of definitions of the members of the value. Refer to definitions for allowed definitions in types. Options will be discussed further below.

A class is defined using the `class` keyword:

    class <name> [: <options>] {
        <members>
    }

Similarly to the definition of a value, `<name>` indicates the name of the class, and `<members>` is a sequence of members of the class.

Actors are also defined using the `class` keyword as above. A class is an actor if either the `on <thread>` option is present, or if it inherits from an actor.

## Members

Types may contain definitions of functions (that become member functions), constructors, and member variables. The two latter may only appear inside types, and are described below.

Similarly to top-level definitions, it is possible to specify visibility of members either by prepending the visibility modifier to each member, or by specifying them for many members at once (e.g. `private:`).

## Member Variables

A member variable is defined as follows:

    <type> <name> [= <initializer>];

Here, <type> is the name of the type of the variable, and `<name>` is the name of the variable. An initializer may also be specified. If specified, the initializer is used to initialize the variable if it is not explicitly initialized to some other value in the `init`-block in a constructor. If no initializer is specified, and no value is present in the `init` block, the default constructor is used if it exists.

## Constructors

Basic Storm attempts to ensure that it is not possible to access uninitialized variables, and thereby accidentally accessing non-nullable types that have the value null. Because of this, constructors are treated specially in Basic Storm. They are defined using a special syntax as follows:

    init(<parameters>) {}

Similarly to function declarations, `<parameters>` is a list of comma-separated parameters to the constructor. If the constructor is inside an actor that requires a thread to its constructor, the first parameter must be of the type `Thread`.

What makes constructors special is that they need to contain an `init` block. The `init` block represents actually creating the instance by initializing all member variables. An initialization block has the following form in general:

    init[(<parameters>)] {
        <name> = <initializer>;
        <name>(<ctor-parameters>);
        ...
    }

The first part, the optional parenthesis with parameters, is used to pass any required parameters to the constructor of the parent class. If no parameters are required, or if parameters have already been passed earlier, this part can be omitted.

The next part contains a list of all variables that should be initialized. These either have the form `<name> = <initializer>;`, which creates the variable by copying the result from an expression, or the form `<name>(<ctor-params>);`, which creates the variable by calling the appropriate constructor. Any variables that are not mentioned in the list are initialized using the initializer specified where the member variable was declared. If no initializer was specified, the default constructor is used if it exists, otherwise an error is raised.

It is worth noting that the order in which variables are initialized does not necessarily match the order in which the variables are listed in the `init` block. Rather, the system initializes them in the order they appear in memory.

Since the `init` block is special since it represents the creation of the object itself. As such, the `this` variable is only accessible after the `init` block has been executed. This is best illustrated with an example:

    class MyClass {
        Int a;
        Int b;

        init(Int b) {
            // Here, 'this' does not exist. We can therefore not access any members.
            a = 10; // Invalid, no instance yet.

            init {
                a = 1;
                // This works as expected. The left hand side has to refer to a
                // member variable. The right hand side can not refer to a member
                // variable, as we don't yet have an instance. It must therefore
                // refer to the parameter.
                b = b;
            }

            // Now we can access the members:
            a = 10; // Valid, we have an instance.
        }
    }

In certain situations it might be useful to create the object in two stages. First, call the constructor of a super class, and then initialize the parts of the derived class. This can be done by explicitly calling `super(<parameters>)` before the `init` block. If this is done, no parameters may be provided to `init`, as the parent class' constructor has already been called. This can be illustrated by the following class, that inherits from `MyClass` above:

    class MyDerivedClass extends MyClass {
        Int c;
        Int d;

        init(Int p, Int q) {
            // Here, 'this' does not exist.
            a = 10; // Invalid, no instance yet.
            c = 10; // Invalid, no instance yet.

            super(p);
            // Here, 'this' is of the type MyClass, since the super class is created.
            a = 10; // Valid, MyClass is created.
            c = 10; // Invalid, this is of type MyClass, which does not contain 'c'.

            init {
                c = q;
                d = q + 10;
            }

            // Now we can access all members.
            a = 10; // Valid, we have an instance.
            c = 10; // Valid, 'this' is now of type MyDerivedClass.
        }
    }

In certain situations, multiple constructors perform similar actions. In such situations it is useful to use another constructor to initialize the object instead of implementing the logic once again. This can be achieved using delegating constructors using the keyword `self` instead of `init` and `super`:

    class MyClass {
        Int x;

        // The constructor that performs all the work:
        init(Int a) {
            init { x = a; }
        }

        // Constructor that provides a default value:
        init() {
            // Delegate to the constructor above.
            self(5);
        }
    }

## Cast Constructors

By default, Basic Storm is restrictive with automatic typecasting. In some cases it is, however, convenient to allow Basic Storm to automatically convert between types. To achieve this, it is possible to declare a constructor as a cast constructor. This is a constructor that takes a single parameter. Since it is marked as a cast constructor, Basic Storm may use it to automatically convert from one type to another. A cast constructor is defined using the keyword `cast` instead of `init`. The syntax is otherwise identical to regular constructors.

## Options

As with functions, it is possible to specify options to types as well. Options are specified by adding a colon (`:`) after the type name, and specifying each option separated by commas. The following options are provided by Basic Storm. Extensions may add more options by extending the rule `lang:bs:SClassOption`, or by declaring a function that accepts a `core:lang:Type` as a parameter.

- `extends <name>`

  Make the type extend another type. Not possible to use together with `on`.

- `on <thread>`

  Only usable with classes. Makes the class into an actor that runs on the specified, named, thread. All members of the class need to execute on the specified thread. If called by other threads, the system automatically sends a message to the appropriate thread. Note that it is possible to use both `on` and `extends` in order to specify that this subclass of the actor always needs to execute on a specific thread, while superclasses may not obey the same restriction.

- `on ?`

  Only usable with classes. Makes the class into an actor that executes on a thread known only at runtime. The thread is specified as the first parameter to all constructors (a `Thread` needs to be specified explicitly, and it may not have a name).

- `final`

  Marks the type as final, which means that it is not possible for other classes to inherit from the type.

- `serializable`

  Requires including `util:serialize`. Adds members required for serialization and deserialization of the type. Only supported for values and classes.

Two options are special: `extends` and `on`. If one of these is the only option, it may be specified without the colon.