Reading facts
A rule can name a fact directly — amount > 1000 — and for a fact you know is present, that is the
right thing to write.
For everything else there is in, and the difference is not convenience.
Why the readers exist
Section titled “Why the readers exist”A bare fact reference aborts the execution when the fact is missing. Every non-retracted rule is evaluated every cycle, and a failed evaluation discards the whole run — including output other rules already wrote. One optional field turns into a lost execution.
The readers cannot do that:
when in.Eq("status", "submitted") // false when status is absentwhen status == "submitted" // aborts the run when status is absentin.Eq returns false for a fact that is not there. It has no failure mode, so it needs no guard.
That is the whole design: a reader that cannot raise does not need a rule author to remember
anything.
Dotted paths
Section titled “Dotted paths”A key is a path. "invariant.doctype" reads the doctype member of the invariant map.
in.Str("customer.address.city", "")in.EqNum("totals.amount", 1200.0)There is no separate GetPath surface, deliberately — ten functions where five will do is ten
things to choose wrongly between.
| Situation | Behaviour |
|---|---|
| A literal dot in a key | Escape it: "Work Phone Ext\\." |
| A key whose split would give an empty segment | Treated as literal, not as a path |
A trailing dot, like "Work Phone Ext." | Safe with no escaping, for the reason above |
Presence and equality
Section titled “Presence and equality”| Call | Returns | Notes |
|---|---|---|
in.Has(path) | bool | Whether anything resolves at that path |
in.Eq(path, value) | bool | String equality. False when absent |
in.EqNum(path, value) | bool | Numeric equality. False when absent |
These three are the ones to reach for in a when. They are total: every input produces a true or a
false, never a failure.
rule RouteSubmitted "submitted claims go to review" salience 100 { when in.Eq("status", "submitted") && in.EqNum("amount", 0.0) == false then out.Set("queue", "review");}Typed readers
Section titled “Typed readers”Each takes a default, which is what it returns when the path is missing or the value is another type. No guard, no abort.
| Call | Returns |
|---|---|
in.Str(path, default) | String |
in.Int(path, default) | Integer |
in.Double(path, default) | Float |
in.Bool(path, default) | Boolean |
in.Date(path) | A date; zero when absent |
in.Map(path) | A nested object |
in.Rows(path) | A list of records |
in.Value(path) | The typed value, or null |
out.Set("city", in.Str("customer.address.city", "UNKNOWN"));out.Set("lines", in.Rows("invoice.lines"));Passing the default explicitly is the point — the rule states what absence means instead of leaving it to whatever the zero value happens to be.
The short forms
Section titled “The short forms”in.GetStr, in.GetInt, in.GetFloat, in.GetBool and in.GetMap are the same readers with the
default fixed at the zero value: in.GetStr(k) is in.Str(k, "").
Use the explicit form when absence means something. Use the short form when the zero value is the right answer anyway.
Scratch memory
Section titled “Scratch memory”Separate from facts, and unchanged: in.MemSet, in.MemGet, in.MemGetStr, in.MemGetRows,
in.MemDelete, in.MemClear, in.GetMemAsMap, and in.NewMapWithValues for building a map inline.
Choosing
Section titled “Choosing”| You want to | Write |
|---|---|
| Compare a fact you know is present | The bare name — amount > 1000 |
| Compare a fact that might be absent | in.Eq / in.EqNum |
| Read a value with a meaningful fallback | in.Str(path, "UNKNOWN") |
| Read a nested member | A dotted path |
| Ask whether something arrived at all | in.Has(path) |
See also
Section titled “See also”- Writing rules — structure, salience and the output envelope
- Writing output —
out, dotted keys and attributes - Functions — the complete callable surface