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](md:) 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](md: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:

```bs
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:

```bs
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`:

```bs
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.
