# Recursion conventions in Unison

You do not need to annotate recursive functions with their return type for a program to typecheck.

```
sum listOfNats = match listOfNats with
[] -> 0
head +: tail -> head + (sum tail)
sum [9,8,7,6]
```

Unison supports tail call elimination. Functions in tail call position (including mutually recursive functions) are evaluated without growing the stack.

# Effectful recursion

Recursive code can perform effects too. When your code performs an ability for some kind of computational effect, your function signature should include anability requirementin curly braces in the return type of the function. See below for an example.

```
use Nat - ==
loop : Nat ->{Stream Nat} ()
loop = cases
n
| n == 0 -> ()
| otherwise ->
emit n
loop (n - 1)
toList! '(loop 10)โงจ[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
```

Many of thehigher-order functionson data types in the`base`

library are already ability polymorphic. In the signature for`lib.base.data.List.map`

,`lib.base.data.List.map : (a ->{๐} b) -> [a] ->{๐} [b]`

,the`{๐}`

symbol in thelambdaargument means that the transformation function`a -> b`

can perform an effect in the process of mapping over each element.