# labels » discussion

"It's hard to know exactly how useful this is in practice, since I've never had cause to write mutually recursive functions, nor have I been able to think of a non-trivial example. However it's there."

It's not there just because it's fancy. If you need a non-trivial exemple, here is one.

1. We have the long multiplication product which is faster for small integers (say less than 1000 digits) but slower for bigger integers.

```let long_mult_big (a: big_int) (b: big_int) =
let i = ref 0
and j = ref (Array.length b-1) in
let result = shift_big (scale_up_big a b.(!i)) !j
in begin
while !j > 0 do
incr i; decr j;
let _ = add_big result (shift_big (scale_up_big a b.(!i)) !j)
in ();
done;
result
end;;
```

2. We have the Karatsuba product wich is faster than "long_mult_big" for integers bigger than say 1000 digits.

3. We want "mult_big", a general product that offers best performance regardless integer size, we implement it using mutual recursion:

```let karatsuba_threshold = 1000;;
```
```let rec mult_big (a: big_int) (b: big_int) =
if Array.length a < Array.length b then
mult_big b a
else if Array.length b < karatsuba_threshold then
long_mult_big a b
else
karatsuba_mult_big a b
and karatsuba_mult_big (p: big_int) (q: big_int) =
assert (Array.length p >= Array.length q);
let len_p = Array.length p  in
let len_q = Array.length q  in
let     n = len_p / 2       in
let     a = Array.sub p 0 (len_p - n) in
let     b = normalize p n   in
if len_q > n then
let     c = Array.sub q 0 (len_q - n) in
let     d = normalize q n in
let    ac = mult_big a c  in
let    bd = mult_big b d  in
let ad_bc = sub_big (sub_big (mult_big (add_big a b) (sum_big c d)) ac) bd
in