---
title: "Functions and reducers — API reference"
description: "The reducers and scalar built-ins callable from a quario expression, and how a registered host function relates to them."
url: "https://getquario.com/docs/reference/functions-and-reducers"
---

# Functions and reducers

Two kinds of function are callable without registering anything. A registered
host function of the same name shadows either.

## Aggregate reducers

You declare them under `aggregates` on the report or on a group.

| Reducer | Result | Empty |
| --- | --- | --- |
| `sum:=expr` | total of `expr` | `0` |
| `count` | number of rows | `0` |
| `countDistinct:=expr` | distinct values of `expr` | `0` |
| `avg:=expr` | mean of `expr` | `null` |
| `min:=expr` | smallest `expr` | `null` |
| `max:=expr` | largest `expr` | `null` |
| `first:=expr` | `expr` on the first row in scope | `null` |
| `last:=expr` | `expr` on the last row in scope | `null` |

`count` takes no expression. Every other reducer takes the form
`name:=expression`. Give `avg`, `min`, `max`, `first` and `last` a visible marker
where an empty set matters.

`first` and `last` are the only reducers that read the order of the rows they
fold, so what a scope gives them matters. A report folds after `where`, its
`sort` and its `take`. A group that declares a `sort` and no `take` folds its
partition before it orders it. Neither skips a null.

## Run reducers

You declare them under `run` and read each one as `run.<name>` on a detail row.
They’re the eight above, plus one.

| Reducer | `run.<name>` on each row |
| --- | --- |
| `sum:=expr` | cumulative sum up to and including this row |
| `count` | 1-based running count |
| `countDistinct:=expr` | distinct values seen so far |
| `avg:=expr` | cumulative mean so far |
| `min:=expr`, `max:=expr` | running extreme so far |
| `first:=expr` | `expr` of the first row in this scope |
| `last:=expr` | `expr` of this row — the identity, which is what `@` already says |
| `prev:=expr` | `expr` of the previous row, `null` on the first |

Scope decides the reset. A `run` block on the report persists across the
document. A `run` block on a group starts again at each instance. Run names
can’t repeat across the report and nested groups, because every run value
shares one `run` object.

## Scalar built-ins

One value in, one value out. These are function calls only, never a reducer
declaration, so `"total": "round:=@.amt"` is a definition error.

| Function | Result |
| --- | --- |
| `round(x, n?)` | `x` to `n` decimal places, halves away from zero |
| `floor(x, n?)` | `x` to `n` decimal places, towards negative infinity |
| `ceil(x, n?)` | `x` to `n` decimal places, towards positive infinity |
| `abs(x)` | the magnitude of `x` |

They round the decimal you wrote, not the double it’s stored as, so
`round(2.675, 2)` is `2.68`.

`n` defaults to `0` and must be a number from 0 to 100. A fractional `n`
truncates to whole places. Any other `n` is an error naming the cell and the
call. A non-finite `x` passes through untouched rather than folding to
zero.

`min` and `max` are reducer names and aren’t scalar two-argument functions.
`min(1, 2)` is a render error saying so. `trunc` isn’t built in.

## Inline reducers

A reducer also folds an array on the row itself.

```json title="an inline reducer"
{ "value": "{{ sum(@.lines, l => l.total) }}" }
```

## Registered functions

```ts title="signature"
type FunctionRegistry = Record<string, (...args: any[]) => any>
```

You pass the registry as the second argument to `report` or `plan`. Registered
functions count as trusted host configuration, unlike the definition that calls
them. A compiled report lists the ones it calls on `report.functions`, each as a
`{ name, arity, doc? }` signature in call-first-seen order.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://getquario.com/"},{"@type":"ListItem","position":2,"name":"Docs","item":"https://getquario.com/docs"},{"@type":"ListItem","position":3,"name":"Functions and reducers","item":"https://getquario.com/docs/reference/functions-and-reducers"}]}
```
