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.
Syntax
Kinds are written using kind annotations, which enclose
a kind in angle brackets:
<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 ).
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:
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.
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 | <_> |
Compound Kinds
Kinds compose structurally according to the data structures they describe.
Data Structure | Kind Syntax | Example | Meaning |
|---|---|---|---|
Matrix |
| <[u8]:2,3> |
|
Set |
| <{u8}:3> | Set of 3 |
Record |
| <{x<u8>,y<string>}> | Record with fields |
Map |
| <{string:i32}> | Map from |
Table |
| <|x<u8>,y<string>|:3> | Table with columns |
Tuple |
| <(u8,string,bool)> | Ordered tuple of heterogeneous values |
Compound kinds are recursively derived from the kinds of their constituent elements.
Kind Annotations
Kind annotations may be used in expressions to specify or constrain the kind of a value.
Literals
Defines x as an unsigned 8-bit integer with value 42.
Variables
Constrains y to always have kind <u8>.
Conversions
[f64]:1,3
converts [f64]:1,3 -> [u8]:1,3
Conversions succeed only when a valid transformation exists, otherwise a compile-time error is raised.
Matrix Reshaping
[f64]:1,6
reshapes to [i32]:2,3
Matrices may be reshaped to compatible dimensions using kind annotations.
Custom Kinds
Users may define custom kinds as aliases of existing kinds:
<T>:=<S>Example:
<point3>:=<[f64]:3>Usage:
p1<point3>:=[123]p2<point3>:=[45]--Error: expected 3 elements
Custom kinds introduce semantic meaning without changing runtime representation.
Enumerations
Enumerations (enums) define a fixed set of named variants.
The kind of the enum is .
The possible values are:
:color/red:color/green:color/blue
Example:
Invalid variants are rejected:
example2<color>:=:color/yellow-- Error, yellow not in enum
Enums are kinds and participate in all kind-based reasoning.