Even if a custom function does not mutate state nor cause side-effects, it may still be volatile, i.e. it depends on the external environment and is not pure.
A perfect example is a function that gets the current time – obviously each run will return a different value!
The optimizer, when using
OptimizationLevel::Full, will merrily assume that all functions are pure,
so when it finds constant arguments (or none) it eagerly executes the function call and replaces it with the result.
This causes the script to behave differently from the intended semantics.
Therefore, avoid using
OptimizationLevel::Full if non-pure custom types and/or functions are involved.