Develop
f { model }
It is inspired by DDD, EventSourcing and Functional programming communities, yet implements these ideas and concepts in idiomatic Kotlin/TypeScript/Rust, which in turn makes our code
- - less error-prone,
- - easier to understand,
- - easier to test,
- - type-safe and thread-safe


// Restaurant Commands
export type RestaurantCommand =
| CreateRestaurantCommand
| ChangeRestaurantMenuCommand
| PlaceOrderCommand;
export type CreateRestaurantCommand = {
readonly decider: "Restaurant";
readonly kind: "CreateRestaurantCommand";
readonly id: RestaurantId;
readonly name: RestaurantName;
readonly menu: RestaurantMenu;
};
export type ChangeRestaurantMenuCommand = {
readonly decider: "Restaurant";
readonly kind: "ChangeRestaurantMenuCommand";
readonly id: RestaurantId;
readonly menu: RestaurantMenu;
};
...
Data
Two standard classes of algebraic types are:
- PRODUCT types
(i.e., tuples, pair, struct and data classes)- SUM types
(i.e., enums and sealed interfaces/classes).
Whereas SUM
types let you model the variations within a particular data type, PRODUCT
types help cluster related data into a larger abstraction.
Data model is well typed
! Notice how RestaurantId, RestaurantName and RestaurantMenu
are not of type String
which would provide no value and has no meaning from the type system perspective.
Behaviour
The functions
offer the algebra of manipulating the data in a compositional manner, effectively modeling the behavior.
- -
decide
- exhaustive, pattern matching command handler / takes command and state as parameters, and returns the list of new events - -
evolve
- exhaustive, pattern matching event handler / takes state and event as parameters, and returns the new state - -
react
- exhaustive, pattern matching event handler / takes event, and returns the list of commands that should be executed next.

export const restaurantDecider: Decider<
RestaurantCommand,
Restaurant | null,
RestaurantEvent
> = new Decider<RestaurantCommand, Restaurant | null, RestaurantEvent>(
(command, currentState) => {
// Decide new events based on the current state and the command
// Exhaustive pattern matching on the command
switch (command.kind) {
case "CreateRestaurantCommand":
...
Libraries (Kotlin | Rust | TypeScript)
f{model} in Kotlin
Lightweight Kotlin library enabling functional and reactive domain modeling patterns
f(&model) in Rust
Lightweight Rust library enabling functional and safe domain modeling patterns
f(model) in TypeScript
Lightweight TypeScript library enabling functional and algebraic domain modeling patterns
Demo Applications
Language | Source Code |
---|---|
Kotlin (Spring) | |
Kotlin (Ktor) | |
TypeScript | |
Rust (Actix-Web Server) | |
Rust (PostgreSQL Extension) |