Variable Declaration, Assignment, and Sequencing
Variable Declarations with var
and val
Slang uses Scala’s var
and val
constructs for variable
declarations.
val x
- declaresx
, bound to a given value, andx
cannot be reassigned.var y
- declaresy
, bound to a given value, andx
can be reassigned (givingx
a new value).
var i: Z = 0;
// var x: Z; // error: every val/var must be given an initial value
var j: Z = i + 1; // initializers can be expressions
var k = 1; // variable types can be inferred, but not recommended style
i = i + k; // variables declared with var can be reassigned
val b: B = true;
// b = (i == 0) // error: cannot assign to read-only variable b (declared with 'val')
Each Slang variable must explicitly be given an initial value.
In addition, Scala’s mechanism
for indicating a default value is not supported. This follows other
high-assurance languages such as SPARK that require explicit
initialization before variable use to avoid errors associated with
uninitialized variables and to ensure that the programmer/analyst always
has the correct understanding of a variable’s initial value.
A variable’s initial value can be computed from an expression that
references previously declared variables.
A type declaration for variable is optional. Slang’s type inference allows local variables to be declared without a type by inferring it from the initializing expression. However, it is best practice to declare each variable with a type to indicate its intended use and to enable the Slang type checker to detect any unintended mismatches between the intended type of the variable and the type of the initializing expression. Moreover, Slang requires explicit type declaration if the initializing expression is complex (e.g., branching).
Variables declared with var
can be re-assigned, as illustrated by
the update to i
in i = i + k
. Slang uses the symbol
=
for assignment, while ==
is the equality operator
(following Scala, and other languages like Java and C).
“Variables” declared with val
cannot be reassigned. val
declarations are often used as “constants” would be in other
languages (e.g., Java’s final
or C’s const
) and when
supporting a functional programming style for Slang, achieving the
conventional functional programming notion of “identifiers bound to values”.
While it is possible to use var
to declare a variable that is
never updated, explicitly using val
to state the intent that a variable never
changes is a useful specification notion in high-assurance
programming. The use of val
in Slang also has a significant
impact on the way that the declared variable is treated in the Logika
verification infrastructure. For example, since Logika knows that val
variables never change, there is no need for the developer
to state an explicit frame
condition on a non-local val
indicating that its value is
the same in the pre-state as well as the post-state of a method.
Each declared val
on an immutable type introduced above has an implicit
associated “invariant” that constrains its value to always be
its initial value (we will discuss immutable and mutable types in the subsequent
chapters).
Command Sequencing
Command sequencing / command separation in Slang is indicated using
the semicolon ;
as in many other languages. However,
Slang also supports Scala’s line-orientation so
semicolons can sometimes be omitted:
i = i + k // ';' can be omitted in Slang due to Scala's line-orientation
j = k * 2
Stylistically, choosing to use semicolons or not is a personal
preference, though for readability it is best to use one approach consistently.
When adopting the “line-orientation” style, one should be familiar with
Scala’s rules for semicolon inference (give the result) since
some of its outcomes may be non-intuitive.