5. Declarations

Variables must be declared before they are used. Aside from a few special cases, declarations have the following formats:

[<qualifier>] <type> <identifier> [= <expression>];

A declaration creates a variable with an identifier of <identifier>, with type <type>, and optionally a type qualifier of <qualifier>. The two qualifiers are var and const, which qualify the identifier as mutable or immutable, respectively. In Gazprea it is important to remember that if the optional qualifier is omitted the default is const, i.e. variables are immutable by default.

Optionally, a declaration may explicitly initialize the value of the new variable with the value of <expression>.

In Gazprea all variables must be initialized in a well defined manner in order to ensure functional purity. If the variables are not initialized to a known value their initial value might change depending on when the program is run. Gazprea therefore follows a strict RAII-style discipline: every declaration is also an initialization, and no variable is ever observable in an uninitialized state. When the programmer omits the explicit initializer, the compiler implicitly initializes the variable to the default value of its type. The default value is 0 for integer and real, false for boolean, ' ' for character, the empty string "" for string, and the element-wise default for aggregate types (arrays, vectors, tuples, structs). Gazprea has no null value.

For simplicity Gazprea assumes that declarations can only appear at the beginning of a block. For instance this would not be legal in Gazprea:

var integer i = 10;
if (blah) {
  i = i + 1;
  real i = 0;  // Illegal placement of a declaration.
}

because the declaration of the real version of i does not occur at the start of the block.

The following declaration placement is legal:

var integer i = 10;
if (blah) {
  var real i = 0;  // At the start of the block. All good.
  i = i + 1;
}

The declaration of a variable happens after initialization. A program that refers to a variable within its own initialization statement is therefore ill-formed.

/* All of these declarations are illegal, they would result in garbage values. */
integer i = i;
integer[10] v = v[0] * 2;

An error message should be raised about the use of undeclared variables in these cases. If a variable of the same name is declared in an enclosing scope, then it is legal to use that in the initialization of a variable with the same name. For instance:

integer x = 7;
if (true) {
  integer y = x;  /* y gets a value of 7 */
  real x = x; /* Refers to the enclosing scope's 'x', so this is legal */

  /* Now 'x' refers to the real version, with a value of 7.0 */
}

5.1. Special cases

Special cases of declarations are covered in their respective sections.

  1. Arrays

  2. Matrices

  3. Tuples

  4. Globals

  5. Functions

  6. Procedures