Skip to content
kata / a language workbench

blog / Design notes

Three ways to name a type

Why KataScript separates product types, sum types, and interfaces into kind, enum, and type.

Kata

A language’s type vocabulary tells you what questions it considers different. KataScript uses three definitions: kind, enum, and type. They describe a value’s parts, its possible forms, and the behavior it promises.

That distinction is useful before any implementation detail enters the picture.

A kind has parts

A point has an x coordinate and a y coordinate. A kind describes that product: each point contains both fields.

kind Point {
x: Int,
y: Int,
}
let origin = Point { x: 0, y: 0 }
print(origin.x)

The field names belong to the definition. Construction supplies their values, and attribute access retrieves them. This is a concrete data representation.

An enum has alternatives

A computation can produce a value or an error. An enum describes that sum: a particular result takes one form at a time.

The standard library’s Res[T, E] has a successful Val variant and an Err variant. Each carries a different payload. Pattern matching distinguishes them and makes the corresponding data available inside a branch.

let result = Res[Int, Str].Val(42)
match result {
Val(n) -> print("value: {n}"),
Err(message) -> print("error: {message}"),
}

This puts an expected failure in the value model. A caller can inspect it, supply another value, or propagate it using ?. A runtime error from invalid language operations is a separate mechanism; it does not automatically become a Res.Err.

A type describes behavior

An interface says which methods a value should support. It does not choose the fields that implement them. In KataScript, type introduces that abstract interface, and impl Kind as Interface declares conformance.

Iteration is a practical example. The language’s for loop goes through the iterator protocol. An array and a custom counter can have different representations while both exposing the operations that iteration needs. The custom iterator example shows a complete implementation.

Keeping these concepts separate makes the language easier to reason about. A product answers “what is inside?” A sum answers “which case is this?” An interface answers “what can it do?”

Runtime identities

KataScript is dynamically typed. These definitions still matter: the interpreter assigns type identities and checks constructions, annotated parameters, and annotated returns at runtime. Type values can also appear in ordinary expressions; print(Int) is a valid program.

This does not make the current implementation a static type checker. Generic conformance and mutation checks are still developing, and the language status describes the limitations. The design vocabulary is a way to make the intended distinctions explicit as the implementation grows.

For the approved design, read the repository’s type-system decision. For the working syntax, continue with types in the guide.

← Back to blog