Skip to content

Common mistakes ​

Almost every rule that fails to parse fails for one of the reasons below. Each entry shows the form that does not work and the form that does.

Syntax traps ​

Keywords must be uppercase ​

-- Wrong:
if prev_sum > 50 then current_value < 0

-- Right:
IF prev_sum > 50 THEN current_value < 0

All keywords — IF, THEN, AND, OR, NOT, IN, EVERY, SOME — must be fully uppercase. The parser does no case-insensitive matching, so if and If are read as ordinary identifiers, not as the keyword.

Use = for equality, not == ​

-- Wrong:
current_value == 5

-- Right:
current_value = 5

There is one equals sign for equality and one only. == is not an operator in this language.

Comparisons do not chain ​

-- Wrong:
0 < current_value < 10

-- Right:
current_value > 0 AND current_value < 10

Comparison operators are non-associative: each one takes exactly two arithmetic operands, and its result is a boolean that cannot be compared again.

NOT IN is two separate words ​

-- Wrong:
current_value NOTIN (0, 5)

-- Right:
current_value NOT IN (0, 5)

NOTIN is a single identifier as far as the parser is concerned. The two keywords need whitespace between them.

ANY is not a keyword ​

-- Wrong:
ANY d IN digits(prev_sum): d = 9

-- Right:
SOME d IN digits(prev_sum): d = 9

There are exactly two quantifiers, EVERY and SOME. ANY, ALL and EXISTS are not part of the language.

Keywords must be separated by whitespace or punctuation ​

-- Wrong (IFprev_sum is treated as a single identifier):
IFprev_sum > 0 THEN current_value < 10

-- Right:
IF prev_sum > 0 THEN current_value < 10

A keyword is only recognised when the character next to it is a space, a parenthesis, a comma, a colon, or the end of the rule. Anything else and it merges into the neighbouring identifier.

Quantifiers need both IN and the colon ​

-- Wrong:
EVERY d digits(prev_sum): d <= 5
EVERY d IN digits(prev_sum) d <= 5

-- Right:
EVERY d IN digits(prev_sum): d <= 5

The full shape is EVERY name IN iterable : condition, and none of the three separators — the loop variable, IN, the colon — is optional.

Functions need at least one argument ​

-- Wrong:
digits()

-- Right:
digits(current_value)

Zero-argument calls are not valid syntax. Note also that digitAt takes exactly two arguments, while digits, highest_digit, lowest_digit and number_of_digits take exactly one — see digit functions.

Meaning traps ​

These parse cleanly. They just do not mean what they look like they mean.

NOT is looser than a comparison ​

-- These are the same rule:
NOT current_value > 5
NOT (current_value > 5)

NOT applies to the whole comparison to its right, never to just the left operand. If you want "the negative of current_value is greater than 5", write the arithmetic explicitly.

A quantifier body runs to the end of the expression ​

-- Probably not what you meant — current_sum > 0 is inside the loop:
EVERY d IN digits(prev_sum): d < 9 AND current_sum > 0

-- Two independent conditions:
(EVERY d IN digits(prev_sum): d < 9) AND current_sum > 0

Everything after the colon is a full condition, so it keeps consuming AND and OR clauses. Parenthesize the quantifier when you want it to stop.

AND binds tighter than OR ​

-- Parses as: a OR (b AND c)
prev_sum > 50 OR step_index = 0 AND current_value > 0

-- If you meant (a OR b) AND c:
(prev_sum > 50 OR step_index = 0) AND current_value > 0

When in doubt, parenthesize

Parentheses are free and never change a correct expression's meaning. Adding them to any rule that mixes AND with OR, or that puts a quantifier next to another clause, costs nothing and removes the whole class of bug above.

Negative tests pass on null place variables ​

-- Intended as "never a 9", but permits every multi-place value:
formula != 9

-- Requires a single affected place first, then tests the formula:
place IN (1, 10, 100, 1000) AND formula != 9

On a candidate like +47 that touches two decimal places, place, formula and digitBefore are all null — so formula != 9 is true and the step is allowed. See decimal places for the full explanation and for digitAt, the multi-place-safe alternative.

Reference and cookbook for mental-math rule and recipe authoring.