Specify evaluation order regarding functions
-term = {J()}
msg = {I(G(F(), named: ""), H())}, {-term}, {K()}
Functions are written in the host language and can both observe and mutate the global state (as well as the bundle they are called from), so order of evaluation should be defined for better portability.
Implementations should be allowed to skip evaluating functions when they hit their internal limits (neccessary for #277).
If we over-specify here, we could end up eliminating some big possible optimizations. For example, an implementation might want to pre-evaluate constant expressions (such as -term above), so in terms of evaluation will do it at compile time, not runtime. This depends, of course, on functions being pure - see #294.
One use case for this would be a OSNAME() function which takes no arguments and therefore an optimizing implementation could run it at compile/deploy time (without special knowledge of the function), and produce smaller bundles for each OS.
Oh, yes, everything I said before only applies to impure functions. An implementation is free to reorder or drop calls to pure ones as long as the result stays the same, and nobody is going to notice these changes, because functions are pure. This opens broad possibilities for constant folding and common subexpression elimination. But that requires knowledge which functions are pure and which are not.