Skip to main content

logic-and-fallback


title: Logic & Fallback sidebar_position: 4

Logic & Fallback

Part of the function and operator catalog. Every example shown below is executed as an assertion by the engine's own test suite (examples.test.ts), so a result shown here is a result the engine actually produces for that input.

IF

IF(condition: any value, thenValue: any value, elseValue: any value) -> any value

Evaluates only the branch its condition selects — the untaken branch is never evaluated at all, so a branch that would divide by zero or read an absent path is safe to write as long as it is never the one taken. Laziness here is not an optimisation: with every arithmetic error hard-failing the run, an eagerly-evaluated IF could not be used as a guard at all. The condition goes through the one condition-position rule: a boolean answers itself, null counts as false, and anything else is a coded error.

Examples:

  • IF(true, 1, 2)
    • result: "1"
  • IF(false, 1, 2)
    • result: "2"
  • IF(input.flag, 1, 2)
    • context: {"flag":null}
    • result: "2"
  • IF(exists(input.divisor), input.total / input.divisor, 0)
    • context: {"total":10,"divisor":2}
    • result: "5.00000000000000000000"
  • IF(exists(input.divisor), input.total / input.divisor, 0)
    • context: {"total":10}
    • result: "0"
  • IF(INDEXOF(input.text, input.needle) == -1, 'not found', 'found')
    • context: {"text":"abcabc","needle":"b"}
    • result: "found"
  • IF(INDEXOF(input.text, input.needle) == -1, 'not found', 'found')
    • context: {"text":"abc","needle":"z"}
    • result: "not found"
  • IF('x', 1, 2)
    • fails with EXPR_CONDITION_NOT_BOOLEAN

COALESCE

COALESCE(value: any value, ...) -> any value

Returns its first argument that is neither absent nor an explicit null, evaluating arguments left to right and never evaluating any argument after the answer — an argument after the answer that would divide by zero does not fail the expression. Skips an absent path as readily as an explicit null, so a default written for a genuinely optional field works either way. An argument whose own evaluation raises an error still fails the expression (skipping a real failure would be a silent absorb) — only absence and null are skipped. Every argument absent or null is its own coded error, distinct from the collection-lookup no-match code, so a caller can tell a failed fallback chain from a failed lookup.

Examples:

  • COALESCE(1, 2)
    • result: "1"
  • COALESCE(input.a, 2)
    • context: {"a":null}
    • result: "2"
  • COALESCE(input.a, input.b, 3)
    • context: {"a":null,"b":null}
    • result: "3"
  • COALESCE(input.a, input.b)
    • context: {"b":5}
    • result: "5"
  • COALESCE(input.a, 1 / 0)
    • context: {"a":5}
    • result: "5"
  • COALESCE(input.a, input.b)
    • fails with EXPR_COALESCE_EXHAUSTED