The autocalc
variable controls the evaluation scheme of the EDEN interpreter.
When it is 1 (default) or non-zero, the interpreter will try to evaluate
all definitions (if they are evaluable, i.e. all their source variables
are defined); otherwise (autocalc is zero) the interpreter puts the suspended
definitions in a queue.
Before the interpreter evaluates a definition, it tests whether all its source variables are defined, i.e. their UpToDate flags are true. However, the interpreter is not intelligent enough to identify variables referenced by a definition indirectly. For instance,
func F { para N; return N + Z; } Y is F(1);
Function F
references the (global) variable Z
,
but the interpreter does not know about that. When Y
is defined, the interpreter thinks that Y
depends on
F
only, and proceeds to evaluate Y
and thus
evaluate F
. However, F
finds that Z
is undefined. In this example, F
returns the sum of
Z
and the first parameter which produces @
when Z
is @
However, some operators and most of
the statements produce an error when the expected data types are not met.
Of course, if we defined Z
before the introduction of
Y
, it may not cause an error. However, if we introduce
Z
after that of Y
, we are in the risk.
Hence, the result of computation seems to be sensitive to the order of
definitions. Despite of this ordering problem, redefining Z
would not cause Y
to be updated. This may not be the
intended behaviour sometimes. There are two ways to get around it:
autocalc
to 0
before the introduction of all definitions. After
all definitions are defined, set autocalc
to 1
again. By doing so, the
evaluation of definitions is delayed. For instance,
autocalc = 0; /* ... other statements ... */ func F { para N; return N + Z; } Y is F(1); Z is 10; /* ... other statements ... */ autocalc = 1;However, this method does not solve the re-evaluation problem.
Z
to F
. For example,
func F { para N; return N + Z; } proc touch_F : Z { touch(&F); } Y is F(1); Z is 10;Because now change of
Z
will induce a change to
F
, Y
is indirectly dependent
upon Z
, and Y
can't be evaluated until Z
is defined. Also Y will be re-evaluated
when Z
is re-defined. This point is not true for the former solution.
In fact, the interpreter should generate such dependency for function
specifications.
func F: Z { para N; return N + Z; }or
func F { para N; return N + Z; } Z ~> [F]to impose dependency would not work because in both cases a change of
Z
will call the function F
(as if it is an action). This is an error
because a parameter is needed to calculate F
.