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' ‘(' typeIDin' expr ‘)' stmt

SPL'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.

The SPL compiler has special handling for the following 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 ‘)' stmt

A 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