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.
Syntax
Kinds are written using kind annotations, which enclose
a kind in angle brackets:
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:
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.
Kind Membership (∈, ∉)
The set membership operators are also defined for kinds:
value ∈returnstruewhenvalueconforms tovalue ∉returnstruewhenvaluedoes not conform to
Examples:
true
42∉<string>--true
This also applies to enum kinds (including payload variants):
true
:red("300")∈<color>--false
Custom Kinds
Users may define custom kinds as aliases of existing kinds:
Example:
Usage:
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 , and The possible values are:
:red:green:blue
Example:
Invalid variants are rejected:
Error, yellow not in enum
Enums are kinds and participate in all kind-based reasoning. Enum variants are atoms, which are globally unique, immutable symbols, so namespace collisions are possible if another module defines the same variant name. To avoid this, you can use qualified names:
Which means the same thing as :red, but is guaranteed to be unique even if another module defines :red as well.
Variants with payload kinds
Enum variants may optionally carry data. Payload kinds can be written either inline (ok) or with parentheses (ok():
In this enum:
okrequires au64payloaderrorrequires astringpayloadtimeoutcarries no payload
Assignments with the wrong payload kind are rejected:
Error: expected u64 payload
Enum kinds in pattern matching
Enums participate in pattern matching like other kinds, including payload destructuring:
When matching enum kinds, arms should be exhaustive (cover every variant or use *). Non-exhaustive matches are reported as compile-time errors.