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

The list functions that make a list of a list or ask about its items (DMN 1.6, section 10.3.4.4, Table 76):
`append`, `concatenate`, `distinct values`, `flatten`, `index of`, `insert before`, `list contains`,
`list replace`, `remove`, `reverse`, `sort` (section 10.3.4.9), `sublist` and `union`. They are a part of
`Feel.Builtin.List`, which has the others and says what it is that they share.

## Positions

`insert before`, `remove`, `list replace` and `sublist` take a position as footnotes 1 to 3 of the table
have it. It is a whole number, a fraction being cut off, that is not 0 and from `-L` to `L` for a list of
`L` items: 1 is the first item and -1 the last. Anything else, an empty list included, is out of the domain:
`null`, with an `:argument_out_of_domain` error. So `insert before` cannot put an item after the last one,
and `insert before([], 1, x)` is `null` (notes, AE-31).

`sublist` takes a length from 1 to what is left from the start on, or none, or `null`, which is none.

## The items

`append` adds each argument after the first as one item, a list as well: `append([1], [2])` is `[1, [2]]`.
`concatenate` and `union` put the items of the lists after one another, and `union` leaves out those that
have been before. `flatten` takes every list out of every list. `reverse`, `distinct values`, `index of`
and `list contains` are as their names say; `index of` gives `[]` where there is no match.

Items are equal as `=` says (`Feel.Runtime.Compare`): `1` and `1.0` are, so are two lists of equal items. Two
items that cannot be compared, a number and a string, are not equal here, and neither are two that are
`null` in `=` (notes, AE-34); `null` is equal to `null` (Table 50), so `index of([1, null], null)` is `[2]`.
`distinct values` keeps the first of equal items, and it and `union` do not compare every pair of them
(`Feel.Runtime.EqualItems`).

**The length of the result** of `concatenate` and `flatten` is counted while their lists are walked, and a result over
`max_list_length` is refused at the first item past it, with the error that the finished list would get, and is not
made: the same list can be an argument a thousand times, or in a list a thousand times (`for i in 1..1000 return xs`).
`union` cannot be refused by the length of the lists together, for `union(xs, xs)` is the items of `xs`, and takes the
lists one after the other when they are over the limit together. The others make a list that is not longer
than their argument, or than their argument and the items that the call itself has, and are checked when they are made.

## list replace

Both forms are written. The one that takes a function, `list replace(list, match, newItem)`, calls `match(item,
newItem)` for each item, in order, and the item is replaced by `newItem` where that is `true` (`Feel.Runtime.Invoke`,
D-82). A `match` that is not a function of two parameters that gives a boolean, by its signature (`function(item,
newItem) item` gives what `item` is, so it is not one), is out of the domain, as it is in the TCK (1155); the types
it declares for its parameters do not matter. What the
calls report is reported, and the call of `match` for an item that is `null` or an error is not `true`, so that item stays.

A list argument is a list, and a value that is not a list is the list of it (section 10.3.2.9.4), so
`list replace(1, 1, 5)` is `[5]` (the TCK, 1155). `null` is neither: the call is out of the domain.

## sort

`sort(list, precedes)` is a new list of the items, in an order in which `precedes(x, y)` being `true` puts `x`
before `y` (Table 81). It is a **stable** merge sort (D-87, was D-87 for `sort`): of two items for which neither
precedes the other the one that came first stays first, so `sort(rows, function(x, y) x.k < y.k)` keeps the
order of the rows with one `k`. Only a `precedes` that is `true` counts: where it is `false`, `null` or an error
the pair is taken to be in order, and what the call reported is reported (as for `list replace`), so
`sort([3, null, 1], function(x, y) x < y)` does not end the run, and where the `null` goes depends on where it was,
as the table warns ("be careful with nulls"). `precedes` is asked about a pair of different items, `n log n`
times at the most; the length of the list is limited by `max_list_length`, and that is the limit of the work.

`precedes` is checked as `match` of `list replace` is: a function of two parameters that gives a boolean by its
signature. Another value, a function of another number of parameters, and a function that gives what its
parameter is (`function(x, y) x`), make the call `null` with an `:argument_out_of_domain` error, even for a list
that has nothing to sort. A list that is not a list is the list of it, and `null` is out of the domain.

# `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*
