Type definitions

A type definition gives a name to a type,

For example:

composite Main {
  type   Integers = list<int32>;
         MySchema = rstring s, Integers ls;
  graph  /* ... */
         stream<MySchema, tuple<int32 id>> SenSource = FileSource() {
           param file: "SenSource.dat"; format: csv;
         }
}

The type MySchema is defined as a tuple, leaving out the optional constructor tuple<...>. The type can be used in operator invocations. In this case, it is used in "MySchema, tuple<int32 id>", which extends MySchema by adding another attribute "int32 id". Tuples on stream SenSource have the type tuple<rstring s, list<int32> ls, int32 id>, in other words, all attributes of MySchema, plus the additional id attribute.

The syntax of a type definition is:

standAloneTypeDef ::= ‘type' ID=' ( type | tupleBody ) ‘;'
compositeTypeDef  ::= ‘static'?ID=' ( type | tupleBody ) ‘;'

Type definitions in composite operators can be static or non-static. Only static type definitions (with the static modifier) can be used from outside the defining operator with the Op.Type notation. Only non-static type definitions (without the static modifier) can depend on instance-specific entities such as ports, streams, parameters, or other non-static types.

It is common to define a stream whose tuples have the same type as the types of another stream. To minimize syntax checking, SPL allows the name of a stream to refer to its type. For example:

 composite Main {
   type  T = int32 i;
   graph stream<int32 i> S = Beacon() {}
         stream<T>       B = Beacon() {} //using T as type
         stream<S>       C = Beacon() {} //using S as type
 }