ava/functions.md

97 lines
1.8 KiB
Markdown

# Functions
## Syntax
```
[given T1, T2, ... TN]
fn <name>: <input> => <output> :=
<body>
end fn
```
- `TN`: Type declaration (e.g. A :: Show)
- `name`: Follows the rules for [names](names.md)
- `input`: One or more named tuples ([records](records.md)).
- `output`: Some type.
- `body`: Function definition.
Note that `<input> => <output>` is the type of a function.
## Function Definitions
Function definitions are a series of expressions, where the value of the last
expression is returned.
```
fn example: (x: Int32, y: Int32) => Int32
let xx := x + 1
let yy := y + 1
xx * yy
end fn
```
## Calling Functions
Calling a function involves passing that function the tuples it needs.
```
given A :: Show
fn example: (a: A) => String
show(a)
end fn
fn calling_a_function: () => Task[()]
let x := 1
let y := true
let z := "foo"
println(show(x) + show(y) + show(z))
end fn
```
### Calling with Tuples
```
fn example: (x: Int32, y: Int32: z: Int32) => Int32
x + y + z
end fn
let inputs := (10, 20, 30)
example inputs
```
```
fn example: (x: Int32, y: Int32)(z: Int32, w: Int32) => Int32
x + y + z + w
end fn
let in1 := (1, 2)
let in2 := (3, 4)
example in1 in2
example (1, 2) in2
example in1 (3, 4)
```
## Generic Functions
## Referencing Arguments
`@args` refers to function arguments.
- For a single parameter list, it refers to the record.
- For multiple parameter lists, it refers to a tuple containing the lists in
order.
## Lazy Arguments
The `lazy` keyword allows the expression providing the value to have evaluation
deferred until the value is _used_ in the function. If the value is not used,
the expression is never evaluated.
```
fn foo: (lazy x: Int32) => Int32
x * 2
end fn
```
Note that this is equivalent to encoding a parameter as a synchronous effect and
evaluating it to value when needed.