Difference between revisions of "Side effects"
m |
m (added mention of Mutables library) |
||
Line 1: | Line 1: | ||
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. | 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. 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 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 | + | |
+ | Analytica does let you [[Assignment Operator :=|assign]] to a local variable V inside a Definition, for example: | ||
Variable A := BEGIN | Variable A := BEGIN | ||
Local v := 0; | Local v := 0; | ||
Line 9: | Line 10: | ||
But that doesn’t cause referential opacity because the local variable is declared right there in the same definition. | 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. | + | 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]] let's you save the value (possible an array or other complex data structure) as a side effect and read it later. | |
== See also == | == See also == | ||
Line 19: | Line 22: | ||
* [[Assignment Operator :=]] | * [[Assignment Operator :=]] | ||
* [[ComputedBy]] | * [[ComputedBy]] | ||
+ | * [[Mutables library]] |
Revision as of 18:21, 8 January 2025
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 let's you save the value (possible an array or other complex data structure) as a side effect and read it later.
Enable comment auto-refresher