kind
===============================================================================

%% A `kind` is a compositional descriptor that classifies values, defines their
structure, and constrains operations without a separate meta-type system.


Kinds describe the *type*, *structure*, and *properties* of values in Mech. Every value has one or more associated kinds, and kinds themselves are values that participate directly in the language.

Kinds contain information to describe:

- Data type e.g. `i32`, `string`, `bool`, ec.
- Data structure e.g. matrix, set, record, table or tuple
- Data size e.g. matrix dimensions, set size, table rows

(!)> Kinds do *not* indicate whether a value is mutable or immutable. The mutability is determined by the user when the value is created, and is independent of its kind. In other words, mutability is a property of the variable or binding that holds the value, whereas a kind describes the inherent nature of the data contained within the value.

1. Syntax
-------------------------------------------------------------------------------

Kinds are written using *kind annotations*, which enclose
a kind in angle brackets:

~~~mech:disabled
<i32>        -- signed 32-bit integer
<string>    -- string
<[u8]>      -- matrix of u8 values
<(u8,bool)> -- tuple of u8 and bool
~~~

Each data structure has a unique syntax, see (§4).


2. Kinds as Values
-------------------------------------------------------------------------------

Kinds are values in Mech.

This means:

- Kinds can be assigned to variables
- Kinds can be passed, stored, and inspected
- Kinds themselves have kinds

For example:

~~~mech:disabled
x := <u8>
~~~

The value of `x` is {{<u8>}}, and the kind of `x` is {{<<u8>>}}.

(*)> This means the kind of {{<<u8>>}} is {{<<<u8>>>}}, and so on.

3. Simple Kinds
-------------------------------------------------------------------------------

Simple kinds correspond directly to primitive data types.

| Data Type         | Kind                                                  |
|-------------------|-------------------------------------------------------|
| Signed integers   | {{<i8>}}, {{<i16>}}, {{<i32>}}, {{<i64>}}, {{<i128>}} |
| Unsigned integers | {{<u8>}}, {{<u16>}}, {{<u32>}}, {{<u64>}}, {{<u128>}} |
| Floating-point    | {{<f32>}}, {{<f64>}}                                  |
| Rational          | {{<r64>}}                                             |
| Complex           | {{<c64>}}                                             |
| String            | {{<string>}}                                          |
| Boolean           | {{<bool>}}                                            |
| Atom              | {{<:atom>}}                                           |
| Kind              | {{<kind>}}                                            |
| Empty             | {{<_>}}                                               |

4. Compound Kinds
-------------------------------------------------------------------------------

Kinds compose structurally according to the data structures they describe.

| Data Structure | Kind Syntax       | Example                   | Meaning                                 |
|----------------|-------------------|---------------------------|-----------------------------------------|
| Matrix         | `[T]:N,M`         | {{<[u8]:2,3>}}            | `2x3` matrix of `u8` values             |
| Set            | `{T}:N`           | {{<{u8}:3>}}              | Set of 3 `u8` values                    |
| Record         | `{field<T>,...}`  | {{<{x<u8>,y<string>}>}}   | Record with fields `x` and `y`          |
| Map            | `{K:V}`           | {{<{string:i32}>}}        | Map from `string` to `i32`              |
| Table          | `|name<T>,...|:N` | {{<|x<u8>,y<string>|:3>}} | Table with columns `x`,`y` and 3 rows   |
| Tuple          | `(T1,T2,...)`     | {{<(u8,string,bool)>}}    | Ordered tuple of heterogeneous values   |

Compound kinds are recursively derived from the kinds of their constituent elements.

5. Kind Annotations
-------------------------------------------------------------------------------

Kind annotations may be used in expressions to specify or constrain the kind of a value.

(5.1) Literals

~~~mech:ex 5.1
x := 42<u8>
~~~

Defines `x` as an unsigned 8-bit integer with value `42`.

(5.2) Variables

~~~mech:ex 5.2
y<u8> := 10
~~~

Constrains `y` to always have kind {{<u8>}}.

(5.3) Conversions

~~~mech:ex 5.3
x := [1 2 3]         -- `[f64]:1,3`
z<[u8]> := x         -- converts `[f64]:1,3` -> `[u8]:1,3`
~~~

Conversions succeed only when a valid transformation exists, otherwise a compile-time error is raised.

(5.4) Matrix Reshaping

~~~mech:ex 5.4
m := [1 2 3 4 5 6]          -- `[f64]:1,6`
n<[i32]:2,3> := m            -- reshapes to `[i32]:2,3`
~~~

Matrices may be reshaped to compatible dimensions using kind annotations.

6. Custom Kinds
-------------------------------------------------------------------------------

Users may define custom kinds as aliases of existing kinds:

~~~mech:disabled
<T> := <S>
~~~

Example:

~~~mech:disabled
<point3> := <[f64]:3>
~~~

Usage:

~~~mech:disabled
p1<point3> := [1 2 3]
p2<point3> := [4 5]   -- Error: expected 3 elements
~~~

Custom kinds introduce semantic meaning without changing runtime representation.

8. Enumerations
-------------------------------------------------------------------------------

Enumerations (enums) define a fixed set of named variants.

~~~mech:ex 8.1
<color> := red | green | blue
~~~

The kind of the enum is `<color>`.  
The possible values are:

- `:color/red`
- `:color/green`
- `:color/blue`

Example:

~~~mech:ex 8.1
example<color> := :color/green
~~~

Invalid variants are rejected:

~~~mech:disabled
example2<color> := :color/yellow   -- Error, yellow not in enum
~~~

Enums are kinds and participate in all kind-based reasoning.