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":
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, Sets,
Maps). 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.
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).
They run later, in the background, after the action that started them
commits, so they differ from the collection operations in two ways:
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'seach:, and everyfinished:), the body is one call to an action in the same domain, as a subscriber'srun: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).
Markdown for agents: /docs/passing-functions.md.Built from Jadpo main at a707efb.