ava/functions.md

159 lines
2.9 KiB
Markdown

# Functions
- Functions accept a single input and produce an output.
- All functions are inherently curried.
## Private Functions
- Any function may be marked `private`.
- `private` functions are only available in the current scope.
- Scope is file, class, instance, etc. (any function holder)
- `private` functions are NOT exported.
```
given F *
class Functor
given A, B
fn map: (A -> B) -> F A -> F B
end class
instance Functor List
given A, B
fn map: (A -> B) -> [A] -> [B]
case _ [] => []
case f [h : t] => f h : map f t
end fn
end instance
-- Equivalent to F[*[*]]
given F (* *), C, B
fn example: F (C B) -> B
```
```
map (+ 1) [1, 2, 3]
-- produces [2, 3, 4]
-- Assuming F is given, F A -> F B
let plus_one := map (+ 1)
```
note define infix in parens as prefix!!!
```
given F * *
Map String Int32
-- F[*[*]]
given F (* *)
List (List String)
```
## 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.
## Function Composition
```
given A, B, C
fn compose: (f: (B) => C, g: (A) => B) => (A) => C
x => f(g(x))
end fn
```
## Variable Length Argument Lists
This feature is explicitly not supported by Ava. Lists should be used instead.