Statements
Statements are the traditional building blocks of imperative languages. As a streaming language, SPL does not need statements most of the time, but they are permitted inside operator logic and function definitions as a convenience.
SPL's assortment of statements is deliberately simple; this simplicity makes it easy to optimize and easy to map to target languages, leading to better performance and portability.
A variable definition
consists of an optional mutable modifier and a type,
followed by a comma-separated list of variable identifiers with optional
initializer expressions, followed by a semicolon:
varDef ::= ‘mutable'? type ( ID ( ‘=' expr )? )+, ‘;'
An example variable definition is mutable int32 i=2,
j=3;. An immutable variable is deep-immutable: even if it
has a composite value, all parts of that value are immutable too,
recursively. The variable definition syntax is similar to C or Java™, except that the type does
not get tangled up with the variable. For example, SPL does not have
variable definitions like int32 x,y[],z;. Immutable
local variables (without mutable modifier) must be
initialized upon declaration. All variables must be initialized before
use.
A block consists of zero or more statements or type definitions, surrounded by curly braces:
blockStmt ::= ‘{' ( stmt | standAloneTypeDef )* ‘}'
An example block is {type T=int32; T i=0; foo(i,2);}.
Local types and variables that are defined in a block are in
scope for the entire block. Blocks are often used as bodies for control
statements like if/while/for,
or as function bodies.
An expression statement consists of an expression followed by a semicolon:
exprStmt ::= expr ‘;'
An example expression statement is foo(i,2);.
Obviously, the purpose of an expression statement is its side-effect.
The only operators that have non-error side-effects are assignments,
certain function calls, and increment/decrement (++/--)
operators.
An if statement can have an optional else clause:
ifStmt ::= ‘if' ‘(' expr ‘)' stmt ( ‘else' stmt )?Dangling else is
resolved to the innermost if; you can override this
with blocks. SPL does not have a C-style switch statement.
A for statement
loops over the elements of a string, list, set, or map:
forStmt ::= ‘for' ‘(' typeID ‘in' expr ‘)' stmtSPL's for loops
are similar to for (type ID : expr) loops in Java 5,
but use the Python-style in instead of the colon (:).
SPL does not have a C-style 3-part for loop, and
the iterated-over collection becomes immutable during the loop. This
means that SPL for loops are countable loops, which
are less error-prone and permit more optimization opportunities than
traditional loops. A for loop over a string or list
iterates over the elements or characters in index order. A for loop
over a set or map has an implementation-specific iteration order. In
a for loop over a map, the loop variable ID iterates
over the keys; a common idiom is to retrieve the associated value
from the collection in the loop body.
for loops
to generate very efficient code:for (int32 i in range(listVar)) // i is set to 0..size(listVar)-1
for (int32 i in range(limit)) // i is set to 0..limit-1
for (int32 i in range(start, limit)) // i is set to start..limit-1
for (int32 i in range(start, limit, step)) // i is set to start..limit-1 (by step).
// step can be positive or negative.A while statement
looks just like in C or Java™:
whileStmt ::= ‘while' ‘(' expr ‘)' stmtA break statement
abruptly exits a while or for loop:
breakStmt ::= ‘break' ‘;'
A continue statement abruptly jumps to the
next iteration of a while or for loop:
continueStmt ::= ‘continue' ‘;'
A return statement abruptly exits a function,
optionally returning a value:
returnStmt ::= ‘return' expr? ‘;'
To summarize, SPL supports the following assortment of statements:
stmt ::= varDef | blockStmt | exprStmt | ifStmt | forStmt
| whileStmt | breakStmt | continueStmt | returnStmt