Reference
The formula language
On this page ยท 5 sections
The text in a Formula node on a diagram, and the expression in a Math node of a message flow, are written in a small language of their own. It looks like the arithmetic you would write anywhere, it reads like the formula node of the classic tools, and it is not JavaScript: the product reads it with its own interpreter, in the browser and on the station alike, and that interpreter reaches the node's inputs and nothing else. There are no globals to find, no prototypes to climb, no function to call but the maths functions listed here, and a loop that does not end is stopped. That is what lets a project with formulas run on a station whose policy forbids code, and what lets the pages carry a Content-Security-Policy without unsafe-eval. A Function node is the other thing: JavaScript, and treated as code.
An expression
One line without an assignment is an expression, and its value is the node's first output (in a Math node, the payload):
(a - 32) * 5 / 9 sqrt(a * a + b * b) x > 100 ? 100 : x
A body
Several statements assign the outputs by name. Anything assigned that is not an output is a local variable; let, var and const are allowed and mean the same thing:
let r = sqrt(a * a + b * b); angle = atan2(b, a) * 180 / pi; magnitude = r;
if / else, while, do / while and for read as usual, with { } blocks, break and continue; return ends the body, and return value sets the first output:
let sum = 0;
for (let i = 1; i <= n; i++) {
if (i % 2 == 0) continue;
sum += i;
}
odd = sum;
A statement ends at ; or at the end of the line.
What there is
| Numbers | 2, 2.5, .5, 1e-3, 0x1f; the constants pi, PI, E, Infinity, NaN |
| Strings and booleans | "text", 'text', true, false; + joins a string to anything |
| Arithmetic | + - * / %; ^ and ** are a power (2 ^ 10 is 1024; -2 ^ 2 is -4, as in mathematics) |
| Comparison | < <= > >= == != (also === and !==) |
| Logic | !, &&, ||, and test ? yes : no |
| Assignment | = += -= *= /= %=, ++ and --, on a variable only |
| Functions | abs sqrt cbrt pow exp log log10 log2 sin cos tan asin acos atan atan2 sinh cosh tanh floor ceil round trunc sign min max hypot random - also as Math.sqrt and so on, so a formula written for the earlier releases still reads |
| Fields | msg.payload, msg["payload"], list[2], list.length read a field of an input; nothing is written into one |
| Comments | // to the end of the line and /* between */ |
What there is not: new, function, this, typeof, objects made in the formula, calls to anything but the functions above, and a way out. A name that is not an input, a variable, a function or a constant is an error naming it; a syntax error names its line and column and the node shows it in the Error list before the diagram runs.
Limits
A run of one formula is at most 200,000 steps (statements, loop iterations and calls); past that it stops with an error and the outputs are NaN. A Formula node's inputs are numbers (a non-number reads as NaN); a Math node's x is the payload as a number and msg is the whole message.
Changes from the earlier releases
Until 1.14 the Formula and Math nodes were JavaScript evaluated by the page. Formulas made of arithmetic, comparisons and Math. functions read exactly as before. What changed: ^ is a power (it was JavaScript's bitwise XOR), new, function and the page's globals are gone, and a Formula body that used Math. functions still does, while the bare names (sqrt) now also work.