ExpandCollapsePrev Next Index

+ 15.1 Forcing Eager Evaluation

We have seen that given:

  fun myrand: 1 -> int = "rand()" 
    requires header '#include <stdlib.h>'
  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 '#include <stdlib.h>'

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.