The rebellion/type module is broken down into a collection of modules, such as rebellion/type/record and rebellion/type/tuple. Each module is meant for working with a specific kind of data type. However, all of these modules have a few things in common.
Any type created in rebellion/type is a nominal type, not a structural type. This means creating a new type, such as with define-record-type, creates a new named unique type that is distinct from all other types. The functions created by one use of define-record-type will not work on instances created via another use of define-record-type, even if both types are named the same and have exactly the same fields.
All types are created using Racket structure types, and the created struct types can have structure type properties attached to them. Each module typically provides default structure type properties for the types it creates, based on how its types are typically used. These defaults can be freely overriden when desired.
The structure, or shape of a type is distinct from an implementation of that type. Each rebellion/type module reflects this distinction by providing two different interfaces for shapes and implementations. A rebellion/type module for working with kind types provides:
A kind-type? type which describes the shape of a kind type but does not provide any constructors, accessors, or predicates. Two kind-type? values are equal whenever the names, field counts, etc. of the types they describe are equivalent. That is, kind-type? values are compared using structural equality. The term shape of a type or simply shape, refers to a kind-type? value. When used without any qualification, the term type typically refers to such a value as well.
A kind-descriptor? type which provides an actual implementation of a kind type, including a predicate and any relevant constructors and accessors. Such an implementation is called a type descriptor, and allows generically operating on unknown types at runtime. At runtime, the term implementation of a type, or simply implementation, refers to a type descriptor.
A kind descriptor can be created for a type using the make-kind-implementation function provided by the corresponding rebellion/type/kind module. Multiple calls to such a function with the same type will produce distinct implementations that are not equal? to each other, meaning that the rebellion/type modules create generative types.
Each rebellion/type/kind module provides a define-kind-type form that creates a new type and binds its constructor, predicate, and accessors to variables. These forms are how most users of the rebellion/type modules are expected to create types, similar to how most Racket struct types are created with the struct form rather than the dynamic make-struct-type function.
At present, no means of representing compile-time information about types is provided. As a result various related features, such as integration with match are not provided by any rebellion/type modules. However, both a basic represention of compile-time type information and integration with match are intended to happen eventually. More advanced functionality such as a full static type system and compile-time type checker are out of scope for now, but it is hoped that such an effort can either build on or integrate with this library.