# Factorial

```(define (fact n)
(define (recur a n)
(if (zero? n)                   ; the base case
a                           ; returns the accumulator when done
(recur (* a n) (- n 1))))   ; a tail recursion with two parameters
(recur 1 x))                        ; the trampoline
```

named let

```(define (fact n)
(let recur ((a 1) (x x))              ; initial values - 1 and n
(if (zero? n)                    ; the base case
a                            ; returning the accumulator
(recur (* a n) (- n 1)))))   ; a tail-call
```

tail-recursive helper

```factorial n = let loop acc n' = if n' > 1
then loop (acc * n') (n' - 1)
else acc
in loop 1 n
```

with guards

```factorial n = let loop acc n' | n' > 1    = loop (acc * n') (n' - 1)
| otherwise = acc
in loop 1 n
```

inverted let

```factorial n = loop 1 n
where loop acc n' | n' > 1    = loop (acc * n') (n' - 1)
| otherwise = acc
```

n-arity helper

```factorial(N) -> factorial(N, 0).

factorial(0, A) -> A;
factorial(N, A) -> factorial(N-1, A*N).
```

with a guard

```factorial(N, A) when N =:= 0 -> A;
factorial(N, A) -> factorial(N-1, A*N).
```
```(defun factorial (n)
(labels ((recur (a x)
(if (= x 0)
a
(recur (* a x) (- x 1)))))
(recur 1 n)))
```