# Data model

Metalang99 provides four different types of collections, as well as a means for defining and dealing with compound data types. (Type checking is not performed due to performance reasons.)

### Variadics

*Representation:* `x, y, z, ...`.

*Documentation:* [`variadics.h`](https://metalang99.readthedocs.io/en/latest/variadics.html).

Variadics are a comma-separated list of preprocessor tokens. Most of the time, a user will provide variadic arguments to your macro so that you could manipulate them as you want:

\[[`examples/assert_for_each.c`](https://github.com/hirrolot/metalang99/blob/master/examples/assert_for_each.c)]

```c
#include <metalang99.h>

#include <assert.h>

#define ASSERT_FOR_EACH(...)                                                                       \
    do {                                                                                           \
        ML99_EVAL(ML99_variadicsForEach(                                                           \
            ML99_compose(v(ML99_semicoloned), ML99_reify(v(assert))),                              \
            v(__VA_ARGS__)))                                                                       \
    } while (0)

int main(void) {
    ASSERT_FOR_EACH(123 == 123, 2 + 2 == 4, "foo"[1] == 'o');
}
```

Here, `ASSERT_FOR_EACH` accepts variadic arguments, which is communicated by its signature. Internally, it calls [`ML99_variadicsForEach`](https://metalang99.readthedocs.io/en/latest/variadics.html#c.ML99_variadicsForEach) to iterate through each argument, resulting in a number of `assert(...);` statements instead of one `assert(a && b && ...);` (which makes debugging easier because failed assertions will not be collapsed with each other).

### **Tuple**

*Representation:* `(x, y, z, ...)`.

*Documentation:* [`tuple.h`](https://metalang99.readthedocs.io/en/latest/tuple.html).

A tuple is formed by putting variadic arguments into parentheses. Besides a collection-like usage, tuples can simulate C structures; the common pattern is to define a tuple constructor (`rect` below) and accessors of the corresponding fields (`rectWidth` and `rectHeight`):

\[[ `examples/rectangle.c` ](https://github.com/hirrolot/metalang99/blob/master/examples/rectangle.c)]

```c
// Computes the area of a rectangle.

#include <metalang99.h>

#define rect(width, height) ML99_tuple(width, height)
#define rectWidth           ML99_tupleGet(0)
#define rectHeight          ML99_tupleGet(1)

#define rectArea(rect) ML99_mul(rectWidth(rect), rectHeight(rect))

/*
 *                15
 * +------------------------------+
 * |                              |
 * |                              |
 * |                              | 7
 * |                              |
 * |                              |
 * +------------------------------+
 */
#define RECTANGLE rect(v(15), v(7))

ML99_ASSERT_EQ(rectArea(RECTANGLE), v(15 * 7));

int main(void) {}
```

In type theory, tuples are known as [product types](https://en.wikipedia.org/wiki/Product_type).

### **Choice**

*Representation:* `(tag, ...)`*.*

*Documentation:* [`choice.h`](https://metalang99.readthedocs.io/en/latest/choice.html).

A choice type encodes a set of alternatives; each alternative can be constructed by a corresponding *value constructor* and be inspected by the means of *pattern matching:*

\[[ `examples/binary_tree.c` ](https://github.com/hirrolot/metalang99/blob/master/examples/binary_tree.c)]

```c
// Sums all nodes of a binary tree, recursively.

#include <metalang99.h>

#define leaf(x)              ML99_choice(v(leaf), x)
#define node(lhs, data, rhs) ML99_choice(v(node), lhs, data, rhs)

#define sumTree(tree)                     ML99_match(tree, v(sumTree_))
#define sumTree_leaf_IMPL(x)              v(x)
#define sumTree_node_IMPL(lhs, data, rhs) ML99_add3(sumTree(v(lhs)), v(data), sumTree(v(rhs)))

/*
 *         4
 *        / \
 *       /   \
 *      /     \
 *     2       6
 *    / \     / \
 *   1   3   5   7
 */
#define TREE node(node(leaf(v(1)), v(2), leaf(v(3))), v(4), node(leaf(v(5)), v(6), leaf(v(7))))

ML99_ASSERT_EQ(sumTree(TREE), v(28));

int main(void) {}
```

In type theory, choice types are usually referred to as [sum types](https://en.wikipedia.org/wiki/Tagged_union).

### Cons-list

*Representation:* choice type.

*Documentation:* [`list.h`](https://metalang99.readthedocs.io/en/latest/list.html).

A [cons-list](https://en.wikipedia.org/wiki/Cons#Lists) is represented as a choice type with two alternatives: an empty list `ML99_nil()` and a list constructor `ML99_cons(x, xs)`. Cons-list is the most powerful collection:

```c
#include <metalang99.h>

// 3, 3, 3, 3, 3
static int five_threes[] = {
    ML99_LIST_EVAL_COMMA_SEP(ML99_listReplicate(v(5), v(3))),
};

// 5, 4, 3, 2, 1
static int from_5_to_1[] = {
    ML99_LIST_EVAL_COMMA_SEP(ML99_listReverse(ML99_list(v(1, 2, 3, 4, 5)))),
};

// 9, 2, 5
static int lesser_than_10[] = {
    ML99_LIST_EVAL_COMMA_SEP(
        ML99_listFilter(ML99_appl(v(ML99_greater), v(10)), ML99_list(v(9, 2, 11, 13, 5)))),
};
```

Although cons-lists provide many more functions than any other collection, they are also more time and space-consuming. If you can deal with a native representation directly (such as variadics, tuples, or sequences), you should do so. Most of the time, a user will provide variadic arguments to your macro, and the only appropriate operation will be for-each loop (such as [`ML99_variadicsForEach`](https://metalang99.readthedocs.io/en/latest/variadics.html#c.ML99_variadicsForEach)).

However, if you still miss a certain function for native collections, you can always convert your representation to a cons-list via [`ML99_list`](https://metalang99.readthedocs.io/en/latest/list.html#c.ML99_list), [`ML99_listFromSeq`](https://metalang99.readthedocs.io/en/latest/list.html#c.ML99_listFromSeq), etc.

### Sequence

Representation: `(x)(y)(z) ...`.

*Documentation:* [`seq.h`](https://metalang99.readthedocs.io/en/latest/seq.html).

A sequence is yet another fast native collection. A perfect example of using sequences is [Interface99](https://github.com/hirrolot/interface99), which allows us to define a software interface like this:

```c
#define Shape_IFACE                      \
    vfunc( int, perim, const VSelf)      \
    vfunc(void, scale, VSelf, int factor)

interface(Shape);
```

With `vfunc` being defined as follows (simplified):

```c
#define vfunc(ret_ty, name, ...) (ret_ty, name, __VA_ARGS__)
```

Thus, a number of `vfunc` invocations forms a complete sequence. Later, Interface99 works with this sequence via [`ML99_seqForEach`](https://metalang99.readthedocs.io/en/latest/seq.html#c.ML99_seqForEach) and a few other helpful macros.


---

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