Operator invocation head
The head of an operator invocation lists the output and input streams and the name of the operator that processes the data.

All the other information that pertains to the operator invocation is in the operator invocation body, making it possible for users to quickly scan a program's topology. The following SPL code is an example of the more advanced features of operator invocation heads:
composite Main {
graph
stream<list<int32> n, float64 i> SomeLongNameForAnInputStream = Beacon() {}
stream<float64 i> FirstStreamInSecondPort = Beacon() {}
stream<FirstStreamInSecondPort> SecondStreamInSecondPort = Beacon() {}
( stream<int32 a1, int32 a2> SomeLongNameForAnOutputStream as A;
stream<float64 b> AnotherLongNameForAnOutputStream as B
) = MyOperator(
SomeLongNameForAnInputStream as C;
stream<float64 i> FirstStreamInSecondPort, SecondStreamInSecondPort as D
) {
output A: a1=1, a2=max(n);
B: b = C.i + D.i;
}
}
as
A
and as B
). The type lists the attributes
of tuples on the stream; the name can be used as input to other operator
invocations; and the alias can be used internally in this stream's body.
Line 8 of the example shows the name of the operator to invoke, in
this case, MyOperator. Finally, Lines 9 and 10
show two input ports, which are separated by a semicolon. Each has
an optional type, one or more stream names that are separated by commas,
and an optional alias (as C
and as D
).
Port D
combines two input streams, FirstStreamInSecondPort
and SecondStreamInSecondPort
,
separated by commas. The general syntax is:opInvokeHead ::= opOutputs ( 'as' ID )? '=' ID opInputs
opOutputs ::= opOutput | '(' opOutput*; ‘)'
opOutput ::= streamTypeID ( ‘as' ID )?
opInputs ::= '(' portInputs*; ')'
portInputs ::= streamType? ID+, ( 'as' ID )?
A port is a point at which streams connect to an operator invocation. The figure shows ports as little triangles. Each output port produces exactly one output stream, but an input port can combine more than one input stream. When there is exactly one output port, the parentheses around the outputs can be omitted.
The syntax allows as-clauses
in three places. The top-level as-clause gives an operator instance
name; an as-clause on an output port gives an output port alias; and
an as-clause on an input port gives an input port alias. When there
are zero output ports, the empty parentheses and the top-level as-clause
with the operator instance name are mandatory, for example, ()
as A = B()
. The as-clauses with port aliases, however, are
always optional, and are useful to make the operator invocation body
more readable by providing a local short name.
Types on input streams are redundant because they also occur when those streams are defined as outputs of other operator invocations. Nevertheless, you can optionally specify these types when you feel that they make code more readable. This specification can also lead to more understandable compiler error messages when there is a type mismatch. When there are multiple streams on the same input port, tuples that are coming from different streams are interleaved. The order of the interleaving is non-deterministic in the sense that no particular order is imposed by the run time.
streamType ::= 'stream' '<' tupleBody '>'
If there are multiple input streams on the same
port, they must all have the same type. If the type of an input port
is explicitly specified, it must be equivalent to the type of the
streams that are connecting to it. The tupleBody
component
of the stream type can be either a list of attributes, or a list of
tuple types (extension), where identifiers can refer to types of other
streams by their stream names. For details, see Tuples.
as alias
notation, use short stream
names in the first place. Stream names that are too long indicate
that it might be time to decompose the program into composite operators.
For more information, see Composite operators.