# Passing functions

You can pass an inline function only as an argument to a standard-library
operation, such as `list.map` or `list.filter`. It is written with `->`,
read as "produces":

```jadpo
var open: List<Todo> = list.filter(todos, todo -> todo.status == TodoStatus.open)
var titles: List<TodoTitle> = list.map(todos, todo -> todo.title)
```

An inline function:

- is one expression;
- takes its parameter's type from the list;
- may read the variables around it, which is safe because values never
  change;
- can't call actions or use `attempt`.

Functions are not values: you can't store one in a variable or pass one to
your own callables.

The collection operations are under `list.`, `set.` and `map.`
([Lists](lists.md), [Sets](sets.md),
[Maps](maps.md)). Those that take an inline function
include `any`, `all`, `find`, `min_by`, `max_by`, `sort_by` and
`group_by`. Text is put in order with `list.sort_by` and a text key.

## Two parameters

For a few standard operations, an inline function takes two parameters:
`list.zip_with`, `map.filter` and `map.map_values`. Write them in
brackets, separated by a comma: `(key, value) -> ...`. Each takes the type
of what the operation gives it in that place: for `list.zip_with`, an item
from each list; for `map.filter` and `map.map_values`, an entry's key and
its value.

```jadpo
type Loaf = Text {
    min_length: 1
}

type Stock = Int {
    min: 0
}

type Sold = Int {}

/// The loaves with some left, given each loaf and its stock.
function in_stock(stock: Map<Loaf, Stock>) -> Map<Loaf, Stock> {
    return map.filter(stock, (loaf, count) -> count > 0)
}

/// How many of each loaf sold, from the morning's and the evening's
/// counts, taken in the same order.
function sold(morning: List<Stock>, evening: List<Stock>) -> List<Sold> {
    return list.zip_with(morning, evening, (before, after) -> Sold(before - after))
}
```

An inline function with a different number of parameters from what its
operation gives is `type.inline_function_parameters`. One with two
parameters anywhere else is `type.inline_function_placement`, as one with
a single parameter is.

## Names that aren't values

No declaration's name is a value. A type, enum, failure, entity, function,
action, query, library or route group, or a standard namespace such as
`list`, written where a value is read is `type.not_a_value`. The places a
value is read are: a variable's value, an argument, a returned value, a
field or list item, an operand, a condition, a `match` subject, a `set:`,
a route's `run:`, a query's condition, an input's `default:` and a test's
expectation.

A value is one of these:

- built: `Placed { ... }`, `Count(5)`;
- one of an enum's variants: `Status.open`;
- read from a variable, a setting (`config.page_size`) or the clock
  (`clock.now`);
- the result of a call: `helper(...)`.

The error's `next:` gives the one that fits the name.

## Batch helpers

The batch helpers take inline functions written with `->` too: `each:` and
`finished:` of `csv.read`, `csv.write`, `tsv`, `json_lines`, `json.read`,
`json.write` and `batches.each`
([Batches: work over many items](batches-work-over-many-items.md)).
They run later, in the background, after the action that started them
commits, so they differ from the collection operations in two ways:

```jadpo
csv.read(
    import.sheet,
    as: ProductRow,
    each: row -> save_product(row, account: import.account_id),
    finished: summary -> import_finished(summary, import: import.id)
)
```

- Where there is nothing to write to (`each:` when reading,
  `batches.each`'s `each:`, and every `finished:`), the body is one call to
  an action in the same domain, as a subscriber's `run:` is. Where the
  helper writes, `each:` is a pure expression giving the row to write
  (`product -> ProductExportRow { ... }`).
- Values the body reads from around it are saved with the run, the record
  Jadpo keeps of the background work, so only values an entity field could
  hold may be read. Reading anything else is a compile error naming the
  value.

For `batches.each`, an inline function is also a named argument's value.
The body's arguments are the item, a field inside it, or a value read from
around it, which `type.batch_each_invalid` and
`type.batch_capture_not_storable` enforce
([How a run is kept](how-a-run-is-kept.md)).
