# Partial application and function composition

Metalang99 supports [partial application](https://en.wikipedia.org/wiki/Partial_application) -- a technique that allows applying arguments to functions separately, not all-at-once. Consider this:

```c
#define F_IMPL(x, y, z) v(x + y + z)
#define F_ARITY         3

// 1 + 2 + 3
ML99_EVAL(ML99_appl(ML99_appl(ML99_appl(v(F), v(1)), v(2)), v(3)))
```

Alternatively, you can write `ML99_appl2(ML99_appl(F, v(1)), v(2), v(3))` or `ML99_appl3(F, v(1), v(2), v(3))`. It works as follows: first, `F` is applied to `v(1)`, then its arity specifier `F_ARITY` (e.g., the number of parameters it accepts) is decremented; the same happens with `v(2)` and `v(3)`. The point here is that each application is already a valid Metalang99 term: you can pass it to higher-order metafunctions, which is quite handy with lists:

```c
// 4 5 6
ML99_LIST_EVAL(ML99_listMap(ML99_appl(v(ML99_add), v(3)), ML99_list(v(1, 2, 3))))
```

* `ML99_appl(v(ML99_add), v(3))` is a term representing a function that accepts a single natural number and increments it by 3.
* [`ML99_listMap`](https://metalang99.readthedocs.io/en/latest/list.html#c.ML99_listMap) maps each item in our list with this function.
* [`ML99_LIST_EVAL`](https://metalang99.readthedocs.io/en/latest/list.html#c.ML99_LIST_EVAL) evaluates the list and pastes all resulting items sequentially.

Without partial application, the situation becomes rather clumsy:

```c
#define ADD_3_IMPL(x) ML99_add(v(x), v(3))
#define ADD_3_ARITY   1

// 4 5 6
ML99_LIST_EVAL(ML99_listMap(v(ADD_3), ML99_list(v(1, 2, 3))))
```

Partial application is especially useful when you want to capture an environment into a closure. With `ML99_appl`, it becomes remarkably convenient:

```c
#define F_IMPL(x, y) v(x##_##y)
#define F_ARITY      2

// abc_1 abc_2 abc_3
ML99_EVAL(ML99_variadicsForEach(ML99_appl(v(F), v(abc)), v(1, 2, 3)))
```

Read more about partial application [here](https://metalang99.readthedocs.io/en/latest/lang.html#c.ML99_appl).

Another neat functional facility is [function composition](https://en.wikipedia.org/wiki/Function_composition_\(computer_science\)). Put simply, `ML99_compose(f, g)` returns a new metafunction that is identical to first invoking `g` with user-provided arguments, and then invoking `f` with the result of invoking `g`. Take a look at the following macro:

```c
#define TRANSFORM(...)                                                                             \
    ML99_EVAL(ML99_variadicsForEach(ML99_compose(v(ML99_braced), v(ML99_untuple)), v(__VA_ARGS__)))

// { int x; }
// { const char *x, y; }
TRANSFORM((int x;), (const char *x, y;))
```

Here, [`ML99_braced`](https://metalang99.readthedocs.io/en/latest/gen.html#c.ML99_braced) is composed with [`ML99_untuple`](https://metalang99.readthedocs.io/en/latest/tuple.html#c.ML99_untuple):

* `ML99_untuple` removes brackets from provided arguments: `(1, 2, 3)` => `1, 2, 3`.
* `ML99_braced` wraps arguments into curly braces: `1, 2, 3` => `{ 1, 2, 3 }`.
* Overall, `ML99_compose(v(ML99_braced), v(ML99_untuple))` results in `(1, 2, 3)` => `{ 1, 2, 3}`.

Then this function composition is supplied to [`ML99_variadicsForEach`](https://metalang99.readthedocs.io/en/latest/variadics.html#c.ML99_variadicsForEach) to achieve the final result.

Partial application and function composition make metafunctions more reusable, which is the essence of functional programming. All higher-order metafunctions in the Metalang99 standard library use partial application under the hood, so you can pass to them both "raw" function-like macro identifiers such as `v(F)` and partially applied functions as well. Any [Metalang99-compliant macro](https://metalang99.readthedocs.io/en/latest/#definitions) with an arity specifier can be partially applied, and the operation is very cheap.
