-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fine grained trait bounds #496
Comments
Edit: NVM about this, just realized this is handled automatically by the blanket impl of BaseFloat. |
I think an example would be useful here. What kind of stuff you'd be fine graining the trait bounds for? |
Sure! Suppose I have bunch of code that looks like: use num_traits::Zero;
fn make_some_mtx<T: Zero + Copy>() -> [[T;2];2] {
let mtx = [[T::zero(); 2]; 2];
// Maybe do something else with mtx.
mtx
} and for whatever reason I am using arrays, but now i want to use cgmath, so I write: use num_traits::Zero;
use cgmath::Matrix2;
fn make_some_mtx<T: Zero + Copy>() -> Matrix2<T> {
let mtx = Matrix::zero();
// Maybe do something else with mtx.
mtx
} Which wont work since impl<S: BaseFloat> Zero for Matrix2<S> {
#[inline]
fn zero() -> Matrix2<S> {
#[cfg_attr(rustfmt, rustfmt_skip)]
Matrix2::new(
S::zero(), S::zero(),
S::zero(), S::zero(),
)
}
#[inline]
fn is_zero(&self) -> bool {
ulps_eq!(self, &Self::zero())
}
} This means I have to also change my bounds: use num_traits::Zero;
use cgmath::{BaseFloat, Matrix2};
fn make_some_mtx<T: BaseFloat>() -> Matrix2<T> {
let mtx = Matrix::zero();
// Maybe do something else with mtx.
mtx
} So for this particular example, the win isn't too much since I need the bound for ulps_eq as well, but there are other examples like (I personally would suggest a further step and have But even having: impl<S: Zero + Copy + UlpsEq> Zero for Matrix2<S> { ... } would be nice. Again I understand this is opinionated since having a single trait define most scalars has its benefits, which is why it's more of a question. |
Thank you for providing the detailed examples! I agree, this would be a welcome feature. |
Would this make it easier to use fixed precision numbers with cgmath? Having square root would be enough to get stuff like magnitude and distances. I tried implementing enough of Float for the |
I think breaking down the trait bounds may help using types not already implementing all of BaseFloat, but I wasn’t intending to break apart num_traits::Float itself. I think that would be an interesting proposal for num_traits. |
In this context, can/should I think we need to collect concrete examples like those provided by @spearman and @elrnv to figure out how to actually improve the situation. Also someone with a good understanding of the mathematical categorization can help grouping and naming behaviour (traits). |
I think not entirely since BaseFloat and BaseNum have additional useful traits from approx, but probably many bounds don’t need those.
|
This makes the trait more flexible. This contributes to rustgd#496.
This makes the trait more flexible. This contributes to #496.
This is possibly more of a question. Would it be of any interest to the users of cgmath to have more fine grained trait bounds on methods from std::ops to eliminate the need to add BaseNum or BaseFloat trait bounds into generic code in libraries that use cgmath? The motivation here is that it may perhaps be easier to swap in/out cgmath in libraries without modifying the trait bounds on all generic code. I know this may be a moot point at this moment, but seeing as cgmath aims to be one of the simpler and more light-weight matrix libs this might make sense here.
The text was updated successfully, but these errors were encountered: