Hello everyone,
The more I use Rust, the more I am impressed with Rust's solution to many issues. However, I believe introducing scoped shared state (context) could open up entirely new domains of usage for Rust
The problem:
While Rust's borrowing system prevents most of the pitfalls of global mutable state, it does not entirely eliminate the desire for shared state that can be easily accessed in a localized context. There are situations, especially in complex applications, where passing shared state through function parameters becomes verbose and hampers readability.
GUI applications are often built using a component-based architecture. With a scoped shared state, components can be designed to be more modular and reusable. Instead of prop-drilling, components can directly access the data they need from the context, simplifying their interfaces.
The Solution
What if context is Type on it's own, so we could have following:
pub context DbSessionContext {
session: Session;
}
fn main() {
let session = DbSession::new();
let session_context = DbSessionContext { session };
use context session_context {
some_function();
}
}
// fun that utilizes `DbSessionContext` to access db session
fn some_function() {
let data = DbSessionContext::session.get_data();
}
I was inspired by React's Context, and to me it appears like something that should be a language feature on its own.
Note that I don't have deep understanding of Rust implementation, so here is rough idea about potential pros and cons:
pros:
- Simplicity and Explicitness: With
use context
, developers can immediately define the active context, enhancing readability. - Localized Scoping: Contexts are restricted to the block they're used in, preventing inadvertent scope leaks.
- Integration with Traits: Considering that context is a type, it should naturally extend to current trait system, broadening its applicability.
- GUI: This approach proved to be very valuable asset for GUI development in React ecosystem.
cons:
- In scenarios where same contexts overlap, managing and understanding context precedence might become challenging
- Depending on the implementation, there could be compile-time overheads related to checking and managing contexts.
- Potential for Misuse: Developers might be tempted to over-rely on this feature, leading to code that's hard to follow if same contexts overlap or if the origin of the context is far from its usage.
Considerations:
- Error handling:
let data = DbSessionContext::session.get_data();
this line would raise compile-time error ifDbSessionContext
is not used within useDbSessionContext
context instance - I also noticed there is closed thread for this problem, but it has different approach: Blog post: Contexts and capabilities in Rust.
Let me know what you think about this and if you find this approach interesting.