# `Feel.Builtin.List.Aggregate`
[🔗](https://github.com/FeeJai/BDM/blob/feel-v0.1.0/apps/feel/lib/feel/builtin/list/aggregate.ex#L1)

The list functions that make one value of a list of them (DMN 1.6, section 10.3.4.4, Table 76): `count`,
`sum`, `mean`, `median`, `mode`, `stddev`, `product`, `min`, `max`, `all` and `any`. They are a part of
`Feel.Builtin.List`, which has the others and says what it is that they share.

Apart from `count`, each has two forms, `sum(list)` and `sum(n1, ..., nN)`, with at least one argument.
The arguments of the second are the items of the list, so `sum(1, 2, 3)` is `sum([1, 2, 3])` and
`sum(7)` is `sum([7])`. An argument that is `null`, and the only one, is no list and no item: the call is
`null` with an error, as the TCK has it (`all(null)`, 0059).

| Call | Items | Of the empty list |
| ---- | ----- | ----------------- |
| `count(list)` | any | `0` |
| `sum`, `mean` | numbers | `null` |
| `product` | numbers | `null`, with an error |
| `median` | numbers | `null` |
| `stddev` | numbers, two or more | `null`, with an error, as it is for one |
| `mode` | numbers | `[]` |
| `min`, `max` | one kind that has an order (Table 55) | `null` |
| `all`, `any` | booleans, and `null`s | `true` and `false` |

The empty list is `null` as the examples of the specification have it, except where the TCK says that it is
an error (`product([])`, `stddev([])` and `stddev([47])`, 0094 and 0063): the specification has `null` for
those too, and the TCK takes `null` and an error to be the answer for a call that is out of its domain.

An item that is not of the kind the function wants (a `null` included) is out of the domain: `null`, with an
`:argument_out_of_domain` error. It is not left out, which is what the B-FEEL of section 11.3 does, and it
is not an "otherwise" item of `all` and `any`, which the TCK has as an error as well (`all([true, 123, true])`).
A `null` among the booleans is an item as any other: `all([true, null])` is `null`.

## The numbers

The arithmetic is that of `Feel.Runtime.Number`, so each operation rounds to 34 digits, and the order of
the items can be seen in a sum of numbers of very different size. `mean` is the sum divided by the count.
`stddev` is the sample standard deviation: the square root of the sum of the squares of the differences
from the mean, divided by the count less one. `median` of an even count is the mean of the two in the
middle. `mode` has the numbers that are most frequent, ascending, equal by value (`1` and `1.0`), and the
first of each as written.

A result that is too large for a number is out of range: `null`, with an error.

## min and max

The items are compared with `<` and `>` (`Feel.Runtime.Compare`), so they have to be of one kind with an
order: numbers, strings, dates, times, dates and times, or durations of one kind. A list of booleans, of
lists, a `null`, and a mix of kinds are out of the domain, and so is a single item that has no order
(`min([[1]])`). Of equal items it is the first that is the result.

# `functions`

```elixir
@spec functions() :: [Feel.Builtin.Function.t()]
```

The functions of this module, as `Feel.Builtin.Function`s.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
