Rules
Errors · How values convert · Names and case · Order of operations · Shared and plain values · True and false · Variables
Errors
When something goes wrong I stop the script and tell you the file, the line, what happened and — when I have one — a tip for what to try next. A function can also hand back an error as a value with ERROR(code, values). That only stops the script if it gets used as an ordinary value, so the caller can test it first with ISERROR.
How values convert
I convert values for you in a few places, and only these.
A whole number and a float together give a float. / always gives a float and \ always gives a whole number.
A string joins with anything using +: I turn the other side into text. A string times a number repeats the string. The one exception is an array on the left: list + "text" adds the string to the array.
When you compare a string with a number, I read the string as a number, so "5" = 5 and "10" > 9 are true. A string that isn’t a number is not equal to any number, and I can’t put it in order against one.
Dividing by a coordinate, or ordering one with < or >, uses the coordinate’s length: with p = (3, 4), 10 / p is 2.0 and p > 4 is true.
The bit operators &, |, ~, << and >> take whole numbers only — not even a float with nothing after the point.
Nothing else converts. "5" - 1 and (1, 2) + 1 stop me with an error — I’d rather ask than guess!
Names and case
I don’t mind how you capitalise keywords, names and fields: Print, PRINT and print are all the same to me. A map key written in quotes keeps its exact case, and you reach it with map("Key").
A name is a letter or _ followed by letters, digits and _. The reserved words are mine, so they can’t be used as names.
Order of operations
Here’s the order I work things out in, tightest first. Operators on the same row go left to right, except ^. When in doubt, add parentheses — I never mind them.
| Level | Operators |
|---|---|
| 1 | name(args) and .field |
| 2 | ^ |
| 3 | - or ~ in front of a value |
| 4 | * / \ MOD & << >> |
| 5 | + - | ~ |
| 6 | ... TO -> |
| 7 | = <> < > <= >= |
| 8 | NOT |
| 9 | AND |
| 10 | OR |
Shared and plain values
Numbers, strings, ranges, coordinates and vectors are plain values: assigning one makes a separate copy. Arrays, maps and objects are shared: assigning one gives you a second name for the same thing.
True and false
To me, NULL, 0, 0.0 and errors are false. Everything else is true — including an empty string, an empty array and an empty map. Comparisons, AND, OR and NOT give the integers 1 and 0.
Variables
Assigning to a name makes a variable the whole program shares — or, inside a NAMESPACE, one that belongs to that namespace. LOCAL makes one that belongs to the function it’s in, and ATOMIC marks a shared one that several threads change at once. If you read a name that nothing ever assigns, I catch it when the script loads — before a single line has run.