Stream and operator instance names

SPL has rules for giving names to operators, operator instances, streams, and ports.

For example:

type T = int32 x;
composite Main {
  graph
    stream<T> Stream3 = Beacon() {}
    stream<T> Stream4 = Beacon() {}
    (stream<T> Stream1 as S1; stream<T> Stream2 as S2) as OpInstance
      = Custom(Stream3 as S3; Stream4 as S4) { /*...body...*/ }
}

The name Custom identifies the invoked operator, whereas the name OpInstance identifies the operator instance. Names Stream1, Stream2, Stream3, and Stream4 identify streams, whereas names S1, S2, S3, and S4 identify ports and can be only used in the body of the operator invocation.

If the as-clause with the explicit operator instance name (as OpInstance in the example) is missing, then the output stream names serve as operator instance name. For example, in stream<T> A = Foo1(I) { }, the name A identifies both a stream and the operator instance. If there are multiple output streams, then all of them are synonyms for the operator instance. For example, in (stream<T> A; stream<T> B) = Foo2(I), both names A and B identify different streams but the same operator instance. If there are zero output streams, then the operator instance name is mandatory, to make sure tools such as a debugger always has an unambiguous name to refer to an operator instance. For example, () = Foo0(I) is a syntax error, whereas () as FooInstance = Foo0(I) is valid.

Depending on the context, the name of a stream can have different meanings:
  • A stream name refers to a stream when used in a port or as the label for a window, output, or logic clause of an operator invocation. For example, stream<...> B = Functor(A)... refers to stream A in the input port.
  • A stream name refers to the operator instance that defines it when used in dynamic application composition, or in external tools such as a debugger that needs to identify operator instances.
  • A stream name refers to the type of the tuples on the stream when used in a context that expects a type. For example, stream<A> B = ... defines a stream B with the same type as stream A.
  • A stream name refers to the latest tuple on the stream when used in an attribute expression. For example, A.f retrieves the attribute f from the current tuple on stream A.
  • A stream name refers to the list of tuples in the history of the stream when used in a subscript expression. For example, A[1].f retrieves attribute f from the previous tuple on stream A.

Besides simple names for streams and operator instances in the main composite operator, SPL also supports qualified names for streams and operator instances nested in other composite operator invocations. (The difference between a simple name and a qualified name is that a qualified name has qualifier tokens . or :: ). SPL uses an outside-in naming scheme: given a stream with the simple name Z in a composite operator instance with the name X.Y, the qualified stream name is X.Y.Z. The streams C.I, C.J, E.I, and E.J in this figure are good examples for this outside-in naming scheme. Qualified stream or operator instance names are used in dynamic application composition in the Streams IDE or the debugger.