# 6.1 Variables

Felix provides two kinds of variables, `var` and `val`.

## 6.1.1 `var` terms

```  var a : int ;  // uninitialized is ok
a = 2; // mutable is ok
var b = &a; // references are ok
```

A `var` is a storage location, or object containing a value. It is addressable and mutable, and its value is stored at the time of declaration. We say this assignment is evaluated eagerly. A `var` does not need to be initialized, but you may get unexpected results if you don't assign it.

## 6.1.2 `val` terms

```  val a = 1;  // valid
val b; // error, not initialized
var c = &a; // error, not addressable
a = 2; // error, not mutable
```

A `val` is a named expression, it is neither addressable nor mutable, and must be initialised. Its value is that of its expression at the time of evaluation. Vals can be evaluated eagerly like a `var`, but they may also be evaluated lazily. Felix converts the `val` expression replacing its name with the body of its expression.

## 6.1.3 Eager and Lazy

When we talk about computation, the words "eager" and "lazy" mean something very specific. The same expression can be computed in two ways. If it is evaluated eagerly, it will be computed to a value as soon as it is declared. If it is evaluated lazily, it will be computed to a value when it is needed.

There are tradeoffs for each, and it is up to the programmer to determine which is better for the task at hand. If a `var` is never used, you waste some effort computing its result. If a `val` is used, you may pay for the cost of computing its result when you don't want to. And you may pay the cost each time the `val` is used.

The primary motivation for using `val` is to support optimisation. The compiler can choose either eager or lazy evaluation depending on what seems to be most efficient. If the number of uses of the `val` is low, lazy evaluation is usally faster.

## 6.1.4 Indeterminate values

The value represented by a `val` can have an initialiser depending on a variable. When this happens, it is not precisely specified, and we call this indeterminate evaluation. If the initialising expression may throw an exception or otherwise fail to terminate, evaluation is also indeterminate.

For example, in:

```  val num = 10;
val denom = 0;
val quot = num / denom; // division by zero
val result = if denom == 0 then 0 else quot;
println\$ result;
```

Felix cannot determine if the program will print 0 or fail with a division by zero exception. If the compiler decides to evalulate lazily then the above is equivalent to

```  val denom = 0;
println\$ if denom == 0 then 0 else 10 / denom endif;
```

## 6.1.5 Forcing lazy evaluation

Lazy evaluation can be enforced by use of closures, denoted with curly braces `{...`}.

```  val num = 10;
val denom = 0;
val quot = { num / denom }; // defer evaluation
val result =
if denom == 0 then 0
else #quot // evaluate now if control flows here
endif
;
println\$ result;
```

```(2, 1)
0
```