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.