Side effects

A variable A or a function F has a side effect when evaluating it also a changes the value of another variable B. Side effects are the bane of computer programmers because it means you can’t be sure of how B was computed without looking for some other variable or function that may change it, even they may be in a totally different part of the code. Computer scientists term this problem “referential opacity”. It makes code much harder to understand and debug.

Analytica is unusual among computer languages in that it does not allow side effects, except in special cases where they aren’t harmful. In particular, it doesn't let you assign to a global variable using the Assignment Operator :=. This is a major reason why Analytica code is so much easier to write, read, and debug than standard procedural languages like C, C++, Basic, R, Python, and so on.

Analytica does let you assign to a local variable V inside a Definition, for example:

  Variable A := BEGIN
      Local v := 0;
      v := B*C^2
  END;

But that doesn’t cause referential opacity because the local variable is declared right there in the same definition.

The most common cause of side effects (and the consequent opacity) is an assignment to a global variable defined somewhere else. That's why Analytica only allows assignments to global variables in these special cases that avoid referential opacity:

  • You may assign to a global variable in an OnClick or OnChange attribute using the Assignment Operator :=. In these cases, evaluation is triggered by a user action, and the assignment changes the definition of the variable to the assigned value or expression, so you can still see how it was computed. You can't assign to a global variable in a standard Definition.
  • An exception to the "no global assignments" rule is that you may assign to a global variable B in a variable or function A if B is specifically defined as ComputedBy(A). This is useful when it is algorithmically convenient to compute B as well as A in the Definition of A. It doesn’t cause any referential opacity because you can see that B is computed by A right in the Definition of B.

Occasionally, it is useful to save a value in a place where it can be used elsewhere, especially for debugging purposes. The Mutables library lets you save the value (possible an array or other complex data structure) as a side effect and read it later.

See also

Comments


You are not allowed to post comments.