Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: Logic

Logic

Passing functions

On this page

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":

example
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.

example
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:

example
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).

Markdown for agents: /docs/passing-functions.md.Built from Jadpo main at a707efb.