> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gorules.io/llms.txt
> Use this file to discover all available pages before exploring further.

# ZEN expression language

> Complete syntax reference for the ZEN expression language.

ZEN is GoRules' expression language for transforming data and evaluating conditions. It's designed to be readable by non-programmers while powerful enough for complex business logic.

## Two modes

ZEN operates in two modes depending on context:

| Mode           | Used in                          | Example                             |
| -------------- | -------------------------------- | ----------------------------------- |
| **Standard**   | Expression nodes, output columns | `price * quantity * (1 - discount)` |
| **Unary test** | Decision table input columns     | `>= 100`, `[1..10]`, `'US', 'CA'`   |

## Standard mode

Full expressions that return values.

### Literals

```
// Numbers
42
3.14
-17
1e6

// Strings
"hello world"
'single quotes work too'
`template with ${variables}`

// Booleans
true
false

// Null
null

// Arrays
[1, 2, 3]
["a", "b", "c"]

// Objects
{ name: "John", age: 30 }
{ [dynamicKey]: value }
```

### Operators

#### Arithmetic

| Operator | Description    | Example           |
| -------- | -------------- | ----------------- |
| `+`      | Addition       | `5 + 3` → `8`     |
| `-`      | Subtraction    | `10 - 4` → `6`    |
| `*`      | Multiplication | `6 * 7` → `42`    |
| `/`      | Division       | `15 / 3` → `5`    |
| `%`      | Modulo         | `17 % 5` → `2`    |
| `^`      | Power          | `2 ^ 10` → `1024` |

#### Comparison

| Operator | Description      | Example   |
| -------- | ---------------- | --------- |
| `==`     | Equal            | `x == 5`  |
| `!=`     | Not equal        | `x != 0`  |
| `>`      | Greater than     | `x > 10`  |
| `<`      | Less than        | `x < 100` |
| `>=`     | Greater or equal | `x >= 18` |
| `<=`     | Less or equal    | `x <= 65` |

#### Logical

| Operator | Description | Example   |
| -------- | ----------- | --------- |
| `and`    | Logical AND | `a and b` |
| `or`     | Logical OR  | `a or b`  |
| `not`    | Logical NOT | `not a`   |

#### Ternary

```
condition ? valueIfTrue : valueIfFalse

score >= 70 ? "pass" : "fail"
age >= 18 ? "adult" : age >= 13 ? "teen" : "child"
```

#### Null coalescing

Returns the first non-null value:

```
user.nickname ?? user.name ?? "Anonymous"
```

#### Range check

```
// Inclusive range
x in [1..10]      // true if 1 <= x <= 10

// Exclusive range
x in (0..100)     // true if 0 < x < 100

// Mixed
x in [0..100)     // true if 0 <= x < 100
x in (0..100]     // true if 0 < x <= 100

// Negation
x not in [1..10]
```

### Property access

```
// Object properties
customer.name
customer.address.city

// Array indexing
items[0]
items[0].price

// Nested access
order.items[0].product.name
```

### Template strings

```
`Hello, ${name}!`
`Total: ${sum(items)} items`
`Status: ${approved ? 'Approved' : 'Pending'}`
```

### String slicing

Extract substrings using `[start:end]` notation:

```
string[0:5]      // Characters 0-4 (first 5)
string[7:12]     // Characters 7-11
string[7:]       // From index 7 to end
string[:5]       // First 5 characters (0-4)
```

| Expression    | Input             | Result     |
| ------------- | ----------------- | ---------- |
| `string[0:5]` | `"sample_string"` | `"sampl"`  |
| `string[7:]`  | `"sample_string"` | `"string"` |
| `string[:6]`  | `"sample_string"` | `"sample"` |

## Unary test mode

Shorthand syntax used in decision table input columns when a **field name is defined**. The value being tested is implicitly available, allowing you to write conditions without repeating the field name.

When an input column has no field name, standard expression mode is used instead.

### Comparisons

```
> 100         // Greater than 100
< 50          // Less than 50
>= 18         // Greater or equal to 18
<= 65         // Less or equal to 65
== "active"   // Equal to "active"
!= 0          // Not equal to 0
```

### Ranges

```
[1..100]      // Between 1 and 100 (inclusive)
(0..100)      // Between 0 and 100 (exclusive)
[18..65)      // 18 to 64
(0..100]      // 1 to 100
```

### Lists

```
'US', 'CA', 'GB'           // Match any of these strings
1, 2, 3, 5, 8              // Match any of these numbers
"pending", "processing"    // Match any of these
```

### Combined conditions

```
> 0 and < 100              // Between 0 and 100
>= 18 and <= 65            // Working age
< 0 or > 100               // Outside 0-100
```

### Functions in unary mode

```
startsWith($, "PRE-")      // String starts with prefix
contains($, "urgent")      // String contains substring
len($) > 5                 // Length greater than 5
```

The `$` symbol represents the value being tested.

## Closures and iteration

The `#` symbol represents the current element when iterating:

```
map([1, 2, 3], # * 2)                    // [2, 4, 6]
map(items, #.price * #.quantity)         // [totals...]
filter([1, 2, 3, 4, 5], # > 3)           // [4, 5]
some([1, 2, 3], # > 2)                   // true
all([1, 2, 3], # > 0)                    // true
```

### Named aliases

For readability, use `as` to name the current element:

```
map(cart.items as item, item.price * item.quantity)
filter(users as user, user.isActive and user.age >= 18)
some(orders as order, order.status == 'pending')
```

This is equivalent to using `#` but clearer when expressions are complex.

## Assignment

Create values and build objects within expressions.

### Basic assignment

```
a = 5                        // {"a": 5}
name = 'John'                // {"name": "John"}
items = [1, 2, 3]            // {"items": [1, 2, 3]}
config = {debug: true}       // {"config": {"debug": true}}
```

### Property assignment

Assign to nested paths — intermediate objects are created automatically:

```
user.name = 'Alice'                      // {"user": {"name": "Alice"}}
user.profile.bio = 'Developer'           // {"user": {"profile": {"bio": "Developer"}}}
app.config.database.host = 'localhost'   // Creates full nested structure
```

### Multiple assignments

Separate with semicolons:

```
a = 1; b = 2                             // {"a": 1, "b": 2}
user.name = 'Charlie'; user.age = 35     // {"user": {"name": "Charlie", "age": 35}}
```

### Assignment with expressions

```
counter = counter + 1                    // Increment existing value
total = price * quantity                 // Compute from input
fullName = firstName + ' ' + lastName    // String concatenation
doubled = map(numbers, # * 2)            // Array operations
status = score > 70 ? 'pass' : 'fail'    // Conditional
```

### Returning values

The last expression determines the return value:

```
a = 5; b = 10; a + b                     // Returns 15
user.name = 'Eve'; user.name             // Returns "Eve"
config.debug = true; config              // Returns {"debug": true}
config.debug = true; $root               // Returns {"config": {"debug": true}}
```

Use `$root` to return the entire context object.
