## [EN] Variadic Function in OCaml

After understanding the concept of function currying, some ideas arose: isn’t it possible to define a variadic function, which is a function of indefinite arity, in OCaml? In the C programming language, the most famous example might be the `printf` function. The following code is a concrete example of defining and using the variadic function.

``````#include <stdarg.h>
#include <stdio.h>

int
add_em_up (int count,...)
{
va_list ap;
int i, sum;

va_start (ap, count);         /* Initialize the argument list. */

sum = 0;
for (i = 0; i < count; i++)
sum += va_arg (ap, int);    /* Get the next argument value. */

va_end (ap);                  /* Clean up. */
return sum;
}

int
main (void)
{
/* This call prints 16. */
printf ("%d\n", add_em_up (3, 5, 5, 6));

/* This call prints 55. */
printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

return 0;
}
``````

However, OCaml is a static/strongly typed programming language so every function should be defined clearly at the compile time. It means it doesn’t allow to have an indefinite number of arguments. For example, if we define a function `add` that takes two integers `x`, `y`, the type of the function `add` is determined as `int -> int -> int = <fun>`. Adding an unexpected argument `z` will cause an error because the interpreter can’t find the return type in the type chain `int -> int -> int`. Then can we make a variadic function in OCaml? The answer is, interestingly, YES when function currying is exploited.

The trick is to take a function object instead of integers as input. The function object should take the next function object as an input. To be specific, let’s define a function `f1` as `let f1 m f2 = f2 m`. The additional input `m` is to say “I am calling the function f2 with the input m”. The evaluation of `f1 m f2 f3 ... fn` is reduced to `f2 m f3 ... fn` and finally we get `fn m`. Note that each `m` is different for each evaluation. Therefore, we may exploit this property to have `n-1` arguments by defining `f1 ... fn-1` appropriately and the last function `fn` returning the value `m` itself, that is `let fn x = x`. If we want to make an accumulator for an arbitrary number of integers, the function `f1` can be defined as `let f1 i m f2 = f2 (m+i)` to take an integer. The function `add` must provide the initial value `m` by defining as `let add f = f 0`.

Here is the source code:

``````let add f = f 0;;
let arg i m f = f (m+i);;
let end_of_args x = x;;
let three = add (arg 1) (arg 2) end_of_args;;
let six = add (arg 1) (arg 2) (arg 3) end_of_args;;
``````