# Variables

In RuLa, variables that bind to case instances — such as `p is Person` — are called [declarations](/rule-language/declarations.md). This page is about the other kind: **value variables**, which let you capture any intermediate result and give it a name inside the assignment part of a rule.

### What Are Value Variables?

A value variable holds the result of any expression: a number, string, list, dictionary, date, and so on. You define one with [`:=`](/rule-language/operators/special-operators/assign.md), giving it a plain name on the left and the expression on the right.

```
p is Person
---
full_name := CONCAT(p.first_name, ' ', p.last_name)
p.display_name := full_name
```

`full_name` is a value variable. It is computed once and then reused on the next line. Without it, you would have to write the `CONCAT(...)` expression twice.

{% hint style="info" %}
A value variable is local to the rule it is defined in. It is available on all lines that follow its definition, but it does not persist between rules.
{% endhint %}

### Syntax

```
left_side := right_side
```

**Left side** — determines what receives the value:

* A **plain name** (e.g. `net_worth`) creates a local variable available on subsequent lines in the same rule.
* A **field path** (e.g. `p.net_worth`) writes the value into that information field on the instance.

**Right side** — any expression that produces a value: a calculation, a string operation, a conditional expression, a list, a dictionary, and so on.

***

### Examples

#### Storing a calculated value to reuse it

```
p is Person
---
net_worth := p.total_assets - p.total_liabilities
p.net_worth := net_worth
p.risk_score := if net_worth < 0 then high_risk else low_risk end
```

`net_worth` is computed once and referenced twice — once to store the figure and once to derive the risk score from it.

***

#### Cleaning up a string before assignment

```
p is Person
---
normalised := UPPER(TRIM(p.first_name))
p.first_name_normalised := normalised
```

The raw value of `first_name` is trimmed of whitespace and uppercased. The cleaned result is stored in a variable and then written to a separate field.

***

#### Building a list incrementally

```
p is Person
---
base_docs := ['id_copy', 'proof_of_address']
full_docs := if p.nationalities contains us then APPEND(base_docs, 'w8_form') else base_docs end
p.required_documents := full_docs
```

`base_docs` holds the default document list. `full_docs` extends it conditionally. The final list is then assigned to the field.

***

#### Using a variable across multiple assignments

```
c is Contract
p is Person
---
annual_fee := c.aum * 0.0075
p.expected_fee := if annual_fee > 10000 then annual_fee else 10000 end
```

`annual_fee` is derived from the contract and then used in an `if-then-else` to enforce a fee floor before being written to the person.

***

#### Intermediate dictionary for a structured assignment

```
p is Person
---
address := {"street": p.street, "city": p.city, "country": p.domicile}
p.formatted_address := PRETTY_PRINT(address)
```

A dictionary is assembled from several fields into `address`, which is then formatted and stored.

***

### Naming Variables

Variable names:

* Must start with a letter.
* Can contain letters, digits, and underscores.
* Are case-sensitive (`NetWorth` and `net_worth` are two different variables).
* Should be short but descriptive — the goal is to make the rule easier to read, not harder.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.atfinity.io/rule-language/variables.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
