Expression engine architecture, function registry, evaluation lifecycle, and cross-platform parity
Overview
The calculation engine powers all expression evaluation across the MQUAD platform. It handles five expression types using a unified parser and evaluator:
The platform uses a directed acyclic graph (DAG) to manage expression evaluation order:
Node: Each expression keyed by {type}:{question_name} (e.g., calculation:total_score)
Edge: A → B means "A depends on B" (B must be evaluated before A)
Topological Sort: Kahn's algorithm determines evaluation order
Partial Recalculation: When a field changes, getAffectedByChange() returns only the transitive dependents that need re-evaluation
Cycle Detection: DFS with recursion stack; self-references are ignored
Expression Syntax
Literals
Type
Examples
Number
42, -3.14, 0
String
'hello', "world"
Boolean
true(), false()
Null
null
Variable References
${question_name}
References another question's answer by its name field. The dot . represents the current question's value.
Operators
Category
Operators
Precedence
Logical OR
or
1 (lowest)
Logical AND
and
2
Comparison
=, ==, !=, <, >, <=, >=
3
Addition
+, -
4
Multiplication
*, div, mod
5
Unary
-, not, !
6 (highest)
Ternary
if(condition, thenValue, elseValue)
Function Reference
Numeric Functions
Function
Signature
Description
int(v)
any → int?
Truncate to integer
number(v)
any → num?
Convert to number
round(v [, n])
num, int? → num
Round to n decimal places
abs(v)
num → num
Absolute value
min(a, b, ...)
num... → num?
Minimum value
max(a, b, ...)
num... → num?
Maximum value
sum(a, b, ...)
num... → num?
Sum of values
String Functions
Function
Signature
Description
concat(a, b, ...)
any... → string
Concatenate values
join(sep, a, b, ...)
string, any... → string
Join with separator
string(v)
any → string
Convert to string
string-length(v)
string → int
Length of string
substring(s, start [, end])
string, int, int? → string
Extract substring
contains(s, sub)
string, string → bool
Check for substring
starts-with(s, prefix)
string, string → bool
Check prefix
ends-with(s, suffix)
string, string → bool
Check suffix
replace(s, search, repl)
string, string, string → string
Replace all occurrences
regex(v, pattern)
string, string → bool?
Test regex match
Date Functions
Function
Signature
Description
today()
→ string
Current date (yyyy-MM-dd)
now()
→ string
Current datetime (ISO 8601)
date(v)
string → string?
Parse date string
date(y, m, d)
int, int, int → string?
Construct date from components
format-date(d, fmt)
string, string → string
Format date with pattern
days-between(d1, d2)
string, string → int?
Days between dates
today-offset(n)
int → string
Date offset from today
year(d)
string → int?
Extract year
month(d)
string → int?
Extract month (1-12)
day(d)
string → int?
Extract day (1-31)
Selection Functions
Function
Signature
Description
selected(v, choice)
array, string → string
Check choice selected
count-selected(v)
array → int
Count selected choices
selected-at(v, i)
array, int → string
Choice at index
Conditional Functions
Function
Signature
Description
if(cond, t, e)
bool, any, any → any
Conditional
coalesce(a, b, ...)
any... → any?
First non-empty value
not(v)
any → bool
Logical NOT
Utility Functions
Function
Signature
Description
count(v)
any → int
Count items
uuid()
→ string
Generate UUID v4
Evaluation Lifecycle
Form Start
1. Load schema + prefill data2. Resolve default values (date/static eagerly, refs in order)3. Build dependency graph from all expressions4. Evaluate ALL calculation expressions (topological order)5. Render UI
On Field Change
1. Update field value in answers2. Query dependency graph for affected nodes3. Re-evaluate only affected calculation expressions4. Re-check constraints for affected questions5. Re-evaluate relevance for affected questions6. Re-compute choice filters for affected questions7. Update UI
Compatibility
All functions and operators are tested across all three platforms with 114 canonical test cases. See ODK_COMPATIBILITY_MATRIX.md for the current status and SUPPORTED_FUNCTIONS.md for the complete function registry.
Reference Documentation
SUPPORTED_FUNCTIONS.md — Complete function registry with signatures and examples
DEPENDENCY_GRAPH_SPEC.md — Dependency graph data structures and algorithms