# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hirrolot.gitbook.io/metalang99/partial-application.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
