A function is **recursive** if the body of that function calls itself, directly or indirectly.

This is useful for typo correction, such as on credit cards. The last digit is the checksum digit.

- The sum of the digits of 6 is 6.
- The sum of the digits of 2019 is the sum of the digits of 201, plus 9.
- The sum of the digits of 201 is the sum of the digits of 20, plus 1.
- The sum of the digits of 20 is the of the digits of 2, plus 0.
- The sum of the digits of 2 is 2.

- The sum of the digits of 20 is the of the digits of 2, plus 0.

- The sum of the digits of 201 is the sum of the digits of 20, plus 1.

This is recursion.

```
def split(n):
"""Split positive n into all but its last digit and its last digit."""
return n // 10, n % 10
def sum_digits(n):
"""Return the sum of the digits of positive integer n."""
if n < 10:
return n
else:
all_but_last, last = split(n)
return sum_digits(all_but_last) + last
```

Iteration is a special case of recursion:

```
def fact_iter(n):
total, k = 1, 1
while k <= n:
total, k = total*k, k+1
return total
```

The above function is equivalent to the recursive function we wrote before. However, the iterative function runs faster in Python than the recursive function because creating new frames takes a little bit of time. However, other languages process code differently and more efficiently, doing the same thing under the hood for both functions, so the run speed is similar/the same.

The iterative function uses four names: `n, total, k, fact_iter`

. The recursive function does the same thing with just two names: `n, fact`

.

```
def fact(n):
if n == 0:
return 1
else:
return n * fact(n-1)
```

Is `fact`

implemented correctly?
1. Verify the base case
2. Treat `fact`

as a functional abstraction
3. Assume that `fact(n-1)`

is correct
4. Verify that `fact(n)`

is correct

Essentially, assume that `fact`

works for simpler instances of the same problem. If it does, you can generalize your conclusion to *all* uses of `fact`

.

A function `f`

calls a function `g`

which calls `f`

which calls `g`

and so on and so forth.

The Luhn Algorithm is used to verify credit card numbers. From Wikipedia:

First: From the rightmost digit, which is the check digit, moving left, double the value of every second digit; if product of this doubling operation is greater than 9 (e.g., 7 * 2 = 14), then sum the digits of the products (e.g., 10: 1 + 0 = 1, 14: 1 + 4 = 5)

Second: Take the sum of all the digits

The Luhn sum of a valid credit card number is a multiple of 10.

```
def luhn_sum(n):
if n < 10:
return n
else:
all_but_last, last = split(n)
return luhn_sum_double(all_but_last) + last
def luhn_sum_double(n):
all_but_last, last = split(n)
luhn_digit = sum_digits(2 * last)
if n < 10:
return luhn_digit
else:
return luhn_sum(all_but_last) + luhn_digit
```

Formulaic: Iteration is a special case of recursion. Idea: The state of an iteration can be passed as arguments.