Compile-time entities
namespace com.teracloud.sample.myNameSpace; //1
use com.teracloud.anotherNameSpace::*; //2
type T = int32; //3
T mySPLFunction(T x) { return 2 * x; } //4
void myOtherFunction(mutable list<T> a) { a = [99]; } //5
public composite SourceSink { //6
type MyType = int32 i, int32 j; //7
graph stream<MyType> B = FileSource() { param file: "a.dat"; } //8
stream<B> C = SomeOperator(B) { param someParam: sqrt(i) + abs(j); } //9
config logLevel : trace; //10
} //11

Each SPL file belongs to a namespace (Line 1). The use directive
makes entities from other namespaces available under a simple name
(Line 2). For example, instead of com.ibm.anotherNameSpace::SomeOperator
,
you can simply write SomeOperator
(Line 9). An SPL
file contains type definitions (Line 3), function definitions (Lines
4-5), and composite operator definitions (Lines 6-12). A composite
operator can contain a clause with type definitions (Line 7). Streams
are always defined in the graph clause of some composite operator
(Lines 8-9) to encourage reusable code and provide a layer for modularization.
The figure shows how all these compile-time entities fit together.
The start symbol for parsing an SPL file is the compilation unit:
compilationUnit ::= namespace? useDirective*
(compositeDef | functionDef | standAloneTypeDef)*
namespace ::= 'namespace' ID+. ';'
useDirective ::= 'use' ID+. '::' ( '*' | ID ) ';'
A namespace contains all the operators, types, and functions that
are defined in files that belong to the namespace. Thus, a namespace
in SPL is similar to a package in Java™. Like
in Java™ and unlike in C++, there
are no partial qualifiers, that is, if the current namespace is a.b
,
access to members of namespace a.b.c
cannot use just
the suffix c
as a qualifier. However, unlike in Java™, namespace qualifiers use ::
instead of . to
distinguish them from operator member access. For example: my.name.space::myOperator.myType
.
A namespace can also contain primitive operators or native functions.
They are not defined in SPL, but can be invoked from SPL. For example,
Line 9 invokes an operator SomeOperator
, which can
either be a composite operator from another SPL file, or a primitive
operator declared in a primitive operator model file. Similarly, Line
9 invokes two functions sqrt
and abs
,
which can either be non-native functions from another SPL file, or native
functions declared in an XML function model file.
T
(Line 5), FileSource (Line 8), and sqrt
(Line
9). The use directive comes in two forms (similar to Java™); it
can either refer to a single entity by name, or all entities in a namespace by using the wildcard
*
. For
example:namespace test; //1
use your.name.space1::YourOperatorOrType; //2
use your.name.space1::yourFunction; //3
use your.name.space2::*; //4
public composite Comp { /*...*/ } //5
All files have an implicit wildcard use directive for the default
namespaces spl
, spl.adapter
, spl.relational
,
and spl.utility
.