• Reference Guide


Variables serve to store values during the computation. The value stored in a variable can be changed with assignment operators.
A variable is declared using the construct as follows:
var Type flags name
var Type flags name = initial_value
The Type of the variable cannot by an analytic type (i.e. a variable cannot contain, for instance, a computed item).
The flags are used to define a non-strict variable, an l-value variable and a constant variable. These options are described below.
The name of the variable must be an identifier.
If no initial value is specified, the initial value of the variable type is used. For instance, in the case of numbers, it is 0, in the case of string an empty string etc.
As all the Enki language constructs return a value, a variable declaration returns the initial value of the variable as its result.
var Real r = 0.5
The example defines a real number variable initialized to the value 0.5.
If an initial value is specified, the type needs not be specified; it will be inferred from the type of the initial value.
var r = 0.5
is the same as:
var Real r = 0.5

Compound Type Variables

A variable can also be of a compound type. For instance:
var Int[5] arr; // an array of five elements
var String[*] seq; // a sequence
var String|Int str_int; // a union of String and Int
var Union whatever;
// a variable to which any value can be assigned
How to write compound types constants is described in the chapter on data type functions.
When the type of a variable is Union, the actual type of the value stored in the variable can be determined by the operator type. Using variables of a union type (especially an unbound union) is less efficient than using variables with a determined type. Therefore, they should not be used without reason.

L-Value Variables

When an ampersand (&) is used within the variable definition flags, the variable will not contain a direct value, but rather a reference to a data item containing the value. (That is, the value of the variable will be an l-value – see the chapter Data references.) Such a variable is analogous to a parameter passed by reference.
var String &item = document.data.customers.0.name;
A reference to the item variable will return the value of document.data.customers.0.name. Assigning a value to the variable, e.g. item = "Adam", will effectively set the value "Adam" to the data item document.data.customers.0.name.
The reference stored in the variable is changed (so that the variable will further identify another data item) like this:
&item = document.data.customers.1.name;
(Note the ampersand in front of the item variable). See also the data reference operators.

Constant Variables

Using the keyword const among the variable definition flags, the variable is made constant – that is, it will not be possible to change its value. This can be useful for l-value variables – then, it will not be possible to change the value of the data item referred to by the variable. Nonetheless, it will be still possible to change the reference itself.
var String const &item = document.data.customers.0.name;
With this definition, the following can be done:
&item = document.data.customers.1.name;
but this would be an error:
item = "Adam";

Non-Strict Variables

If a question mark (?) is used in variable definition flags, it makes the variable non-strict. A non-strict variable can contain a value of the type Error in addition to the type declared. This enables to intercept errors occurred during the program execution. Details are described in the chapter on error handling.
var Real ?x;
x = 1/y;
The variable declared above is non-strict. That means, if the value of y in the second line is 0, information about the error (division by zero) is stored to the variable x and can be further handled.

Scope of Variable

A variable can be used from the place of its definition onwards up to the end of the function or end of block (whichever comes first). As Enki does not distinguish between expression parentheses and command parentheses, which, in many programming languages, delimit a block span, the block span is determined by the individual Enki language construct used. For instance, the if operator branches are blocks. Therefore, a variable defined in the first branch of an if operator will cease to exist at the end of the branch execution and is not accessible in the other branch nor beyond the if operator.
var Int y;
// here, the variable y can be used
// here, the variable y is not defined
// neither here is defined
A variable defined in a block hides the variable with the same name defined in a superordinate block.
var Int y = 1
var Int y = 2;
// y is 2
// y refers to the outer definition, therefore y is 1
// here, y is 1, too
In some situation, it may be desirable to explicitly limit the scope of a variable. The block statement serves this purpose:
block (expression)
The scope of a variable defined within the expression in the block statement is restricted to the expression.
If it is desired to define a variable accessible in several functions (provided the functions are located at dispels), it can be done in a superordinate data provider.