Eager Operator Evaluation ========================= {{#include ../../links.md}} Most operators are actually function calls, and those functions can be overridden, so whether they are optimized away depends on the situation: ```admonish info.side.wide "No external functions" Rhai guarantees that no external function will be run, which may trigger side-effects (unless the optimization level is [`OptimizationLevel::Full`]). ``` * if the operands are not [constant] values, it is **not** optimized; * if the [operator] is [overloaded][operator overloading], it is **not** optimized because the overloading function may not be _pure_ (i.e. may cause side-effects when called); * if the [operator] is not _built-in_ (see list of [built-in operators]), it is **not** optimized; * if the [operator] is a [built-in operator] for a [standard type][standard types], it is called and replaced by a [constant] result. ```js // The following is most likely generated by machine. const DECISION = 1; // this is an integer, one of the standard types if DECISION == 1 { // this is optimized into 'true' : } else if DECISION == 2 { // this is optimized into 'false' : } else if DECISION == 3 { // this is optimized into 'false' : } else { : } // Or an equivalent using 'switch': switch DECISION { 1 => ..., // this statement is promoted 2 => ..., // this statement is eliminated 3 => ..., // this statement is eliminated _ => ... // this statement is eliminated } ``` Pre-Evaluation of Constant Expressions -------------------------------------- Because of the eager evaluation of [operators][built-in operators] for [standard types], many [constant] expressions will be evaluated and replaced by the result. ```rust let x = (1+2) * 3 - 4/5 % 6; // will be replaced by 'let x = 9' let y = (1 > 2) || (3 <= 4); // will be replaced by 'let y = true' ``` For operators that are not optimized away due to one of the above reasons, the function calls are simply left behind. ```rust // Assume 'new_state' returns some custom type that is NOT one of the standard types. // Also assume that the '==' operator is defined for that custom type. const DECISION_1 = new_state(1); const DECISION_2 = new_state(2); const DECISION_3 = new_state(3); if DECISION == 1 { // NOT optimized away because the operator is not built-in : // and may cause side-effects if called! : } else if DECISION == 2 { // same here, NOT optimized away : } else if DECISION == 3 { // same here, NOT optimized away : } else { : } ``` Alternatively, turn the optimizer to [`OptimizationLevel::Full`].