:title
5. Functions

:content
A function gives a name to a calculation. Parameters describe its input. The declared result type describes its output.

## Define and call a function

:example capy render
function greet(name : capture string) string
{
	-> "Hello, " + name
}

function RENDER()
{
	var name := "Ada"
	print(greet(), "\n")
}

:output
Hello, Ada

:content
The `->` expression supplies the function result. Use `return` when a function must finish early.

## Parameters and defaults

Parameters have names and types:

:example capy render
function label(name : string, suffix : string = "!") string
{
	-> name + suffix
}

function RENDER()
{
	print(label("Capy"), "\n")
}

:content

`label("Capy")` uses the default suffix. Defaults are trailing literals. A direct call can omit them, but a function value keeps the full parameter list.

Capy evaluates arguments once from left to right.

## Capture parameters

A capture parameter uses the caller's variable with the same name when the caller omits its argument. The first example captures `name`.

Write `name : capture Type` for an exact type match. Write `name : capture as Type` to permit one constructor conversion.

Capture parameters follow all ordinary parameters, including parameters with defaults. The caller can also pass an explicit argument.

A missing caller variable is a compile error. The diagnostic names the function and the capture parameter.

A helper that uses request-dependent functions must declare `request : capture dval`. Each helper in a call chain needs that capture.

```capy
function set_title(title : string, request : capture dval)
{
	request.page_title = title
}
```

Handlers bind `request` implicitly. Exported `(dval) dval` functions also capture `request` implicitly. They need no explicit capture declaration.

## Map entry arguments

An argument of the form `key: value` is a map entry. Adjacent map entries form one map argument:

:example capy render
function describe(name : string, options : dval = {}) string
{
	-> name + " " + json_encode(options)
}

function RENDER()
{
	print(describe("list", page: 2, per_page: 20), "\n")
	print(describe("list",
		{
			page: 2,
			per_page: 20
		}
	),
		"\n"
	)
}

:output
list {"page":2,"per_page":20}
list {"page":2,"per_page":20}

:content

Both calls pass the same map and compile to the same code. Use map entries for options and for the input of a unit call.

A map entry does not name a parameter. `describe(name: "list")` passes one map, and the compiler reports that no overload accepts it. A key is an identifier or a string.

An ordinary argument ends the map. In `find(1, page: 2, true)` the call receives `1`, the map `{page: 2}`, and `true`. Two map parameters in sequence need braces for the second map. Struct constructors take ordinary arguments.

## Overloads

Several functions can have the same name when their parameter types differ:

:example capy render
function describe(value : s32) string
{
	-> "integer"
}
function describe(value : string) string
{
	-> "string"
}

function RENDER()
{
	print(describe(42), " ", describe("Ada"), "\n")
}

:content

The argument types select the overload. A result type never selects one.

## Conversion parameters

A parameter declared with `as` permits one constructor conversion:

:example capy render
function show(value : as string)
{
	print(value, "\n")
}

function RENDER()
{
	show(42)
}

:content

The call behaves as if it passed `string(42)`. Capy does not chain several conversions.

## Function values

A function can be stored and called through a typed value:

:example capy render
function double(value : s32) s32
{
	-> value * 2
}

function RENDER()
{
	var operation : function(value : s32) s32 = double
	var answer := operation(21)
	print(answer, "\n")
}

:content

A lambda defines a small function at its point of use:

:example capy render
function RENDER()
{
	var add_one := function(value : s32) s32
	{
		-> value + 1
	}
	print(add_one(41), "\n")
}

:content

A lambda can read outer variables. A captured number, boolean, or string is copied. A captured array, `dval`, or struct is the same object the outer code holds, so the closure can change its contents and the outer code sees the change. A capture cannot be reassigned.

:example capy render
function RENDER()
{
	var offset := 2
	var values := [10]
	var update := function() s64
	{
		values.push(20)
		-> offset + length(values)
	}
	print(update(), " ", values[1], "\n")
}

:content

## Store a callback in a dynamic value

A `dval` can store a named function or a closure for the rest of the request. Read it with its complete function type:

:example capy render
function add_one(value : s32) s32
{
	-> value + 1
}

function RENDER()
{
	var step := s32(2)
	var callbacks := {
		named: add_one,
		captured: function(value : s32) s32
		{
			-> value + step
		}
	}
	var named : function(value : s32) s32 = callbacks.named
	var captured : function(value : s32) s32 = callbacks.captured
	print(named(1), " ", captured(1), "\n")
}

:output
2 3

:content

The function type must match exactly. A mismatch traps. A callable does not cross a public boundary. BRRB, JSON, YAML, and XML replace it with `none`. Maps keep keys. Lists keep indexes.

## Generic and variadic functions

An `any` parameter creates a compile-time generic function. Use it when the same operation is valid for several concrete types.

A variadic parameter collects values into a typed array:

:example capy render
function print_all(...values : as string)
{
	for value := values
	{
		print(value)
	}
}

function RENDER()
{
	print_all("one", " ", "two", "\n")
}

:content

Use `...items` to spread an array into a variadic call.

:see-group
guides

:see
capy-04-expressions-and-control-flow
capy-07-collections-and-records
print
