Skip to content

Commit 3d4355b

Browse files
committed
Move other pages
1 parent 6f0d3bd commit 3d4355b

19 files changed

Lines changed: 419 additions & 545 deletions

docs/contribute.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
sidebar_position: 9
3+
---
4+
5+
# Contribute to CGP
6+
7+
We welcome contributors who are passionate about promoting CGP within the Rust ecosystem. Whether you're a beginner or an experienced Rust developer, there are numerous ways you can contribute to the project.
8+
9+
In this page, we'll explore different ways you can get involved and help grow the CGP community. Your contributions, regardless of your level of expertise, are valuable and appreciated!
10+
11+
## Participate in Discussions
12+
13+
Join the conversation on platforms like [**Discord**](https://discord.gg/Hgk3rCw6pQ), [**GitHub**](https://github.com/orgs/contextgeneric/discussions) or [**Reddit**](https://www.reddit.com/r/cgp/). Whether you have questions about CGP or ideas for new topics or content, these forums are great places to share your thoughts and engage with the community.
14+
15+
## Read The Documentation
16+
17+
We encourage you to explore the documentation available on this website, including the [CGP Patterns](https://patterns.contextgeneric.dev) book. Your feedback is invaluable to us—if you encounter anything confusing or unclear, please let us know so we can improve the content and make it more accessible to everyone.
18+
19+
## Publish Your own CGP Components
20+
21+
The modularity provided by CGP can benefit everyone, even for those who do _not_ care about modularity. An ideal future for CGP is to have a community that publishes large amount of reusable components, that can be used by anyone to build modular applications with minimal application-specific code.
22+
23+
When that happens, it would become possible for CGP to be used by anyone, without having to write their own context-generic code. Instead, the majority of the users will only need to define the wirings of existing components that have been published by the community.
24+
25+
If you _care_ about modularity and would like to contribute, the best way is to start publishing context-generic components, and help build up an ecosystem that benefits the rest of developers.
26+
27+
## Spread on Social Media
28+
29+
Help raise awareness of CGP by sharing it on social media. Follow our official BlueSky account [@contextgeneric.dev](https://bsky.app/profile/contextgeneric.dev) to stay updated on CGP’s development and latest news.
30+
31+
## Write About It
32+
33+
If you find CGP interesting, consider writing your own blog posts or tutorials to share your learning journey. Sharing your insights can help others learn CGP in different ways, and even if the topic is
34+
already covered on the official site, your perspective might make it clearer to others.
35+
36+
## Sponsor Me
37+
38+
If you appreciate my work and want to see CGP gain wider adoption, the best way to support it is to *sponsor* me, regardless of the amount. I have sponsorship pages on [Github Sponsor](https://github.com/sponsors/soareschen/), [Patreon](https://www.patreon.com/c/maybevoid/about), and [Ko-Fi](https://ko-fi.com/maybevoid).
39+
40+
*As with most open-source projects*, I don't expect sponsorship to be enough to allow me to quit my job and work full-time on CGP, or even *with* CGP. *However*, any financial support will significantly boost my confidence in the *value* of my work and encourage me to continue dedicating hundreds of hours of my free time to it instead of other pursuits.
41+
42+
I do hope to eventually spend a year or two working full-time on CGP using my *personal savings*, even if sponsorships don't cover my living expenses. *However*, exponential growth is important, and if I could secure around a quarter of my living expenses through monthly sponsorship, it would reduce some risk and suggest a higher chance of CGP becoming self-sustaining later on.
43+
44+
# Acknowledgement
45+
46+
CGP is created by [Soares Chen](https://maybevoid.com/), with inspiration drawn from various programming languages and paradigms, particularly Haskell typeclasses.
47+
48+
The development of CGP would not have been possible without the strong support of my employer, [Informal Systems](https://informal.systems/). CGP was initially introduced and refined as part of the [Hermes SDK](https://github.com/informalsystems/hermes-sdk/) project, which leverages CGP to build a highly modular relayer for inter-blockchain communication.

docs/index.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
sidebar_position: 1
3+
---
4+
5+
6+
# Introduction
7+
8+
Context-Generic Programming (CGP) is a modular programming paradigm that enables you to bypass the **coherence restrictions** in Rust traits, allowing for **overlapping** and **orphan** implementations of any CGP trait.
9+
10+
You can adapt almost any existing Rust trait to use CGP today by applying the `#[cgp_component]` macro to the trait definition. After this annotation, you can write **named** implementations of the trait using `#[cgp_impl]`, which can be defined without being constrained by the coherence rules. You can then selectively enable and reuse the named implementation for your type using the `delegate_components!` macro.
11+
12+
For instance, we can, in principle, annotate the standard library’s [`Hash`](https://doc.rust-lang.org/std/hash/trait.Hash.html) trait with `#[cgp_component]` like this:
13+
14+
```rust
15+
#[cgp_component(HashProvider)]
16+
pub trait Hash { ... }
17+
```
18+
19+
This change does not affect existing code that uses or implements `Hash`, but it allows for new, potentially overlapping implementations, such as one that works for any type that also implements `Display`:
20+
21+
```rust
22+
#[cgp_impl(HashWithDisplay)]
23+
impl<T: Display> HashProvider for T { ... }
24+
```
25+
26+
You can then apply and reuse this implementation on any type by using the `delegate_components!` macro:
27+
28+
```rust
29+
pub struct MyData { ... }
30+
impl Display for MyData { ... }
31+
32+
delegate_components! {
33+
MyData {
34+
HashProviderComponent: HashWithDisplay,
35+
}
36+
}
37+
```
38+
39+
In this example, `MyData` implements the `Hash` trait by using `delegate_components!` to delegate its implementation to the `HashWithDisplay` provider, identified by the key `HashProviderComponent`. Because `MyData` already implements `Display`, the `Hash` trait is now automatically implemented through CGP via this delegation.
40+
41+
---
42+
43+
# Current Status
44+
45+
As of 2025, it is important to note that CGP remains in its **formative, early stages** of active development. While the potential is genuinely promising, it still has several inevitable rough edges, particularly in key areas such as comprehensive documentation, mature tooling, streamlined debugging techniques, robust community support, and overall ecosystem maturity.
46+
47+
Consequently, embracing CGP for your mission-critical, serious projects comes with inherent challenges, and you should be advised to proceed **at your own discretion and risk**. The primary risk you face is not strictly technical, but rather stems from the current limited support available when you inevitably encounter difficulties while learning or attempting to apply CGP in production.
48+
49+
At this pioneering stage, CGP is an ideal fit for [**early adopters and enthusiastic potential contributors**](/contribute/) who are eager to experiment with the paradigm and actively help to shape its powerful future.
50+
51+
---
52+
53+
# Getting Started
54+
55+
Even though the CGP project is officially still less than one year old, some of the initial documentation and resources you might find have already become slightly outdated, or they have been gracefully superseded by more intuitive and modern patterns. Nevertheless, this section is an attempt to provide you with the very best and most current guidance on how you can effectively begin to learn more about CGP.
56+
57+
## Blog Posts
58+
59+
The most accurate and up-to-date resources concerning CGP are currently available in the form of our [blog posts](/blog). Specifically, we recommend that the blog posts starting from the [**v0.6.2 release onward**](/blog/v0-6-2-release/) will give you a significantly more concise and modern explanation of what CGP is all about.
60+
61+
## Hello World Tutorial
62+
63+
The hands-on [Hello World Tutorial](/docs/tutorials/hello) provides a high-level and clear walkthrough of various fundamental CGP features by using a familiar, simple hello-world style example.
64+
65+
## Book
66+
67+
If your preference is to rigorously understand CGP from its **first principles**, without relying on the specific implementations within the [`cgp` crate](https://github.com/contextgeneric/cgp), your best approach is to dive into our comprehensive book, [Context-Generic Programming Patterns](https://patterns.contextgeneric.dev/). This resource provides a deep, thorough guide to understanding the complex inner workings of CGP.
68+
69+
Please note that this book has not been updated for a while, and you might consider skipping the book entirely if your primary goal is to start using CGP quickly with the absolute minimal learning curve!
70+
71+
## Resources
72+
73+
Make sure to check out the dedicated [Resources](/resources) page, which contains more supplementary materials and various learning tools to help you get up to speed with CGP.

docs/intro.md

Lines changed: 0 additions & 47 deletions
This file was deleted.

docs/overview.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
sidebar_position: 2
3+
---
4+
5+
# Overview
6+
7+
This page provides a quick overview and highlight the key features of CGP. For a deeper dive into the concepts and patterns of CGP, explore our comprehensive book, [Context-Generic Programming Patterns](https://patterns.contextgeneric.dev/).
8+
9+
# Key Features
10+
11+
This section highlights some of the key advantages that Context-Generic Programming (CGP) offers.
12+
13+
## Modular Component System
14+
15+
CGP leverages Rust's powerful trait system to define generic component _interfaces_ that decouple the code that _consumes_ an interface from the code that _implements_ it. This is achieved by introducing:
16+
17+
- **Provider traits**, which define the implementation of a component interface.
18+
- **Consumer traits**, which specify how a component interface is consumed.
19+
20+
By separating provider traits from consumer traits, CGP enables multiple context-generic provider implementations to coexist. This approach circumvents Rust's usual limitation on overlapping or orphaned trait implementations, offering greater flexibility and modularity.
21+
22+
## Highly Expressive Macros
23+
24+
CGP empowers developers to write _abstract programs_ that are generic over a context, including all its associated types and methods. This capability eliminates the need to explicitly specify an extensive list of generic parameters in type signatures, streamlining code structure and readability.
25+
26+
Additionally, CGP offers powerful _macros_ for defining component interfaces and simplifies the process of wiring component implementations for use with a specific context.
27+
28+
With CGP, Rust code can achieve a level of expressiveness comparable to, if not exceeding, that of other popular programming paradigms, such as object-oriented programming and dynamically typed programming.
29+
30+
## Type-Safe Composition
31+
32+
CGP leverages Rust's robust type system to guarantee that all component wiring is _type-safe_, ensuring that any missing dependencies are caught at compile time. It operates entirely within safe Rust, avoiding dynamic typing techniques such as `dyn traits`, `Any`, or runtime reflection.
33+
34+
This strict adherence to type safety ensures that no CGP-specific errors can occur during application runtime, providing developers with greater confidence in their code's reliability.
35+
36+
## No-Std Friendly
37+
38+
CGP enables the creation of _fully abstract programs_ that can be defined without relying on any concrete dependencies — except for other abstract CGP components. This abstraction extends to dependencies such as I/O, runtime, cryptographic operations, and encoding schemes, allowing these concerns to be separated from the core application logic.
39+
40+
As a result, the core logic of an application can be seamlessly instantiated with specialized dependencies, making it compatible with no-std environments. These include embedded systems, operating system kernels, sandboxed environments like WebAssembly, and symbolic execution platforms such as Kani.
41+
42+
## Zero-Cost Abstraction
43+
44+
CGP operates entirely at compile-time, leveraging Rust's type system to ensure correctness without introducing runtime overhead. This approach upholds Rust's hallmark of _zero-cost abstraction_, enabling developers to use CGP's features without sacrificing runtime performance.
45+
46+
47+
# Problems Solved
48+
49+
Here are some common problems in Rust that CGP helps to address.
50+
51+
## Error Handling
52+
53+
Rather than being tied to a specific error crate like `anyhow` or `eyre`, CGP's `HasErrorType` and `CanRaiseError` traits allow the decoupling of core application logic from error handling. This enables concrete applications to choose their preferred error library and select the error-handling strategy that best suits their needs, such as deciding whether or not to include stack traces in errors.
54+
55+
For more detailed information on error handling, refer to the [error handling chapter](https://patterns.contextgeneric.dev/error-handling.html) in our book
56+
57+
## Async Runtime
58+
59+
Rather than committing to a specific runtime crate like `tokio` or `async-std`, CGP enables the application core logic to rely on an abstract runtime context that provides only the features required by the application.
60+
61+
Unlike monolithic runtime traits, an abstract runtime context in CGP does _not_ require a comprehensive or upfront design of all possible runtime features any application might need. This flexibility allows easy switching between concrete runtime implementations, depending on the specific runtime features the application utilizes.
62+
63+
## Overlapping Implementations
64+
65+
A common frustration among Rust programmers is the restriction on overlapping trait implementations. A typical workaround is to use newtype wrappers, but this can become cumbersome when dealing with multiple composite types that need to be extended.
66+
67+
Rust requires a crate to own either the type or the trait for a trait implementation, which often places a significant burden on the author of a new type to implement all the common traits their users might need. This can lead to bloated type definitions, with excessive trait implementations such as `Eq`, `Clone`, `TryFrom`, `Hash`, and `Serialize`. Despite careful design, libraries may still face requests from users to implement less common traits, which can only be implemented by the crate that owns the type.
68+
69+
With the introduction of _provider traits_, CGP removes these restrictions on overlapping implementations. Both the owner and non-owners of a type can define custom implementations for that type. When multiple provider implementations are available, users can choose one and wire it up easily using CGP constructs.
70+
71+
CGP also favors the use of _abstract types_ over newtype wrappers. For instance, a type like `f64` can be directly used for both `Context::Distance` and `Context::Weight`, with the associated types still treated as distinct within the abstract code. CGP also enables specialized provider implementations, even if the crate does not own the primitive type (e.g., `f64`) or the provider trait.
72+
73+
## Dynamic Dispatch
74+
75+
A common approach for newcomers to support polymorphism in Rust is to use dynamic dispatch with `dyn Trait` objects. However, this severely limits the functionality to a restricted subset of _dyn-compatible_ (object-safe) features in Rust. Often, this limitation spreads throughout the entire codebase, requiring non-trivial workarounds for non-dyn-compatible constructs, such as `Clone`.
76+
77+
Even when dynamic dispatch is not used, many Rust programmers rely on ad-hoc polymorphism, defining enums to represent all potential variants of types in the application. This results in numerous `match` expressions scattered across the codebase, making it difficult to decouple logic for each branch. Additionally, adding new variants to the enum becomes challenging, as every branch must be updated, even when the new variant is only used in a small portion of the code.
78+
79+
CGP provides several solutions to address the dynamic dispatch problem by delegating the "assembly" of the variant collection to the concrete context. The core application logic can be written generically over the context and the associated type representing the abstract enum. CGP also facilitates powerful datatype-generic patterns that allow providers for each variant to be implemented separately and combined to work with enums that contain any combination of variants.
80+
81+
## Monolithic Traits
82+
83+
Even without CGP, Rust's trait system provides powerful mechanisms for building abstractions that would be difficult to achieve in other mainstream languages. One common best practice is to write abstract code that is generic over a context type, but this often involves an implicit trait bound tied directly to the generic context.
84+
85+
Unlike CGP, traits in this pattern are typically designed as monolithic, encompassing all the dependencies that the core application might need. Without CGP, an abstract caller must also include all trait bounds required by the generic functions it invokes. As a result, any additional generic trait bounds tend to propagate throughout the codebase, leading developers to combine all these trait bounds into one monolithic trait for convenience.
86+
87+
Monolithic traits can quickly become bottlenecks that prevent large projects from scaling. It's not uncommon for such traits to become bloated with dozens or even hundreds of methods and types. This overgrowth makes it increasingly difficult to introduce new implementations or modify existing ones. Additionally, with Rust's current practices, breaking down or decoupling these monolithic traits into smaller, more manageable traits can be challenging.
88+
89+
CGP offers significant improvements over this traditional pattern, making it possible to write abstract Rust code without the risk of creating unwieldy, monolithic traits. CGP enables the decomposition of large traits into many small, focused traits, each ideally consisting of just a single method or type. This is made possible by the dependency injection pattern used in CGP, which allows implementations to introduce only the minimal trait bounds they need directly within the implementation, rather than bundling everything into a single, monolithic structure.

0 commit comments

Comments
 (0)