-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Problem Statement
The use of abstract types in CGP remains unergonomic due to the need to constantly add a Self:: prefix to all abstract types. This introduces significant cognitive overload, as users would need to first understand how associated types work.
While the idea of associated types are technically quite simple, it still requires additional understanding on top of regular generics. What we should instead do is to try to make abstract types appear as if they are regular generic types.
#[use_type] Abstract Type Importer
Similar to #194 and #195, we can introduce #[use_type] as an abstract type importer in #[cgp_component]. So one can write something like:
#[cgp_component(AreaCalculator)]
#[use_type(HasScalarType::Scalar)]
pub trait CanCalculateArea {
fn area(&self) -> Scalar;
}This would be equivalent to writing:
#[cgp_component(AreaCalculator)]
pub trait CanCalculateArea: HasScalarType {
fn area(&self) -> Self::Scalar;
}The main difference is that with #[use_type], we can have an easier time to explain to the user that we are effectively lazily importing a Scalar type from the context.
This explanation works better because the Rust developer no longer need to understand how supertraits and associated types work. When they see a #[use_type], they can now understand it as a delayed import without needing to understand the remaining concepts.
This also works in synergy with #[cgp_impl] and #[cgp_fn], which can also use #[use_type] to import abstract types from the context.