15.1 Forcing Eager Evaluation
We have seen that given:
fun myrand: 1 -> int = "rand()" requires header ' ' ; fun mytwice : int -> int = "$1+$1"; var result = mytwice (myrand());
that we cannot be sure whether {rand()} is called once or twice. We have seen a solution:
var tmp = myrand(); var result2 = mytwice (tmp);
in which we can force the issue by using a variable initialised to the result of calling {rand()}, which Felix guarantees will be executed at most once, when control flows through the initialisation.
We have seen we could fix this problem by:
fun mytwice2 (var x:int) => mytwice(x);
which uses a Felix function with a var
parameter to force
eager evaluation of the argument, or we could instead
make a generator:
gen myrand2: 1 -> int = "rand()" requires header ' ' ;
which causes Felix to create and initialise a temporary
whether the twice
function has a var parameter or not.
15.1.1 Inline named variables
There are two other ways to achieve this result. You can specify any sub-expression is to be lifted out and assigned to a new variable as so:
var result3 = mytwice (myrand() as var tmp1) + mytwice(tmp);
The {as var} operator here has a precedence just lower than a comparison. As you can see you can reuse the variable in the expression. Suprisingly this will work too:
var result4 = mytwice (tmp2) + mytwice (myrand() as tmp2);
because the initialisation of tmp2 is lifted out of the expression. Take note, however, of the rule that such variable initialisations are done in order of writing (strictly, by recursive descent of the parse tree).
A variable created this way is exactly the same as writing:
var tmp3 = myrand(); var result5 = mytwice (tmp3) + mytwice (tmp3);
so the variable is still available after the expression using it completes.
15.1.2 Inline anonymous variables
It is also possible to just write this:
var result6 = mytwice (var rand());
which creates an unnamed temporary variable initialied by the following sub-expression.
From these examples I hope you will begin to picture
a Felix var
like a traditional variable in C
and associate the notation with eager evaluation.
We will see in more depth later that a var
is an object
which is a storage location which can contain a value.
In particular, a var
has an address which can be captured
as a pointer value.
In turn such a pointer allows the value stored in a variable
to be modified or replaced. So var
is associated with three
concepts: eager evaluation, addressability, and mutability
which rolled together form a strong concept of an object.