Comments (10)
Thank you for sparking this discussion, @nical !
I feel that traits are on the entirely opposite side of the problem. Traits describe behavior, where the original idea behind mint
was to standardize the content.
Suppose you use a library that exposes something satisfying mint::Vector
trait. Now you want to process it with nalgebra
. What do you do?
The solution I'd prefer is to have mint
describing types only (plus a few From
/Into
conversions). Then we may have another crate (mint_traits
?) with standard traits like Transform3
that are implemented for the standard types as well as (potentially) native types of other libraries.
from mint.
The idea would be that euclid or naglebra would implement ways to make conversion to mint traits easy (like From
).
An interface that wants to be "more standard" could be generic over the mint trait or some trait that describes an easy conversion between the mint trait and nalgebra's structure.
from mint.
Something inspired from this: https://deterministic.space/elegant-apis-in-rust.html#custom-traits-for-input-parameters
from mint.
For example if you look at the lyon_bezier crate, all of the members are publicly exposed so it can't expose an API with standard types unless all members are themselves of that standard type and then I go from having a library that is very nice to use with euclid to one that is a bit awkward to use with every library (not very appealing from my point of view as a user and maintainer of the crate) and more annoying to maintain.
However, the bezier curve segments could maybe be generic over a Point2<F32>
trait that provides the interface I need to do the bezier math. It would make the crate a bit more tedious to write (generics all over the place), but it would seamlessly integrate with the other lyon crates that use euclid or any other math crate that implements the mint traits.
from mint.
If you expose mint
types in that (wonderful!) bezier crate and have a separate library with standard traits that happen to be implemented for mint
types, then it's internals are going to be pretty and easy to maintain.
from mint.
Kinda, but having mint declare data structures and logic (the traits and implementation of the traits), is equivalent to creating a new full featured math library. At this point mint isn't lighter wait than euclid or the others.
Plus, for lyon_bezier to be nice to use with the rest of the lyon crates which heavily use euclid, it needs to store euclid objects (be it explicitly or generically by storing a trait that euclid points implement). If a bezier segment stores its points generically using traits (not types), I can seemlessly integrate with the rest of my code, whereas with mint types I have to jungle between two ways to represent the same thing.
from mint.
is equivalent to creating a new full featured math library
I was just about to put it into README ;)
But yes, that is true. However, the point can be somewhat softened by:
- traits don't have to be in the same crate, could be
mint_traits
. Edit: technically, traits and their implementations would deserve separate (dependent) features. - traits could be behind a non-default feature gate (my preference). Similarly, operators can be gated too.
or lyon_bezier to be nice to use with the rest of the lyon crates which heavily use euclid
It would be as nice to use if the rest of lyon crates was using mint
;)
from mint.
One trouble with traits is that the set of potentially useful operations is much larger, and has a much larger set of design choices to be made, than the set of potentially useful interface types. Mint's current direction allows it to be lightweight and minimal, and imposes no significant design constraints on other libraries. lyon_bezier, for example, would play adequately well with mint by merit of suitable From
/Into
implementations existing for euclid types, rather than having to be invasively refactored into generic, less-predictable, slower-to-compile code.
from mint.
The traits don't need to expose the entire set of potentially useful operations. In fact it could be as small as the set of things you can do out of a mint type, so x()
, y()
, z()
and new(x, y, z)
are enough to provide the same service as mint types if you want to keep it small.
If as a user of the trait you want to add missing operations, you can simply do it, even in a separate crate. For example, injecting a square_length
method to implementors of a trait Vector2<T>
that only exposes x and y:
trait SquareLength<T> {
fn square_length(&self) -> T;
}
impl<V, T> SquareLength<T> for V
where
V: Vector2<T>,
T: Add<Output=T> + Mul<Output=T>
{
fn square_length(&self) -> T {
self.x() * self.x() + self.y() + self.y()
}
}
With mint types, lyon_bezier would have to either copy out every member into an euclid type before doing anything and then back after operations are performed (the methods are on average 5-6 lines long so it is already quite invasive), or have from/into called every time a member is used which is not worth the pain.
I agree with the problem that generics worsen compile times, but I don't see what's less predictable about accessing x through a trait method rather than indexing an array.
Another advantage of traits:
Euclid has a great feature that all vectors and transforms are tagged with units (or spaces depending on how you choose to think of it) in a very ergonomic way. This lets us avoid adding a vector in screen space to a vector in world space, CSS stacking-context space (or one of the dozen other coordinate systems we have to jungle with). This has allowed us to find a lot of bugs (enough bugs to want to maintain a dedicated vector library), and has prevented tons more. mint types basically lose all of the benefits of this feature, because you need to convert into a unit-less vector type at the API boundary where you are exposing your standard types, so you are dropping all of this important type information.
traits can easily let us support this because vectors with different units are different types and so different implementations of the same traits. The trait system naturally won't let you assign a vector in a space to a vector in another space, even if they are expressed generically.
from mint.
It would be as nice to use if the rest of lyon crates was using mint ;)
you don't need to create a new crate if the goal is that everyone switches to it and only uses it (realistically people won't). If that's what we are after, we'd be much better off saying that cgmath is the standard (I'd say euclid but I guess cgmath already has more users), and trying to convince other math libraries to make it easy to interoperate with cgmath.
from mint.
Related Issues (20)
- Serialization HOT 1
- Remove `uninitialized()` in favor of `MaybeUninit`?
- Source files distributed with executable bit set HOT 3
- Bump the crate version to include no_std feature HOT 1
- Quaternion memory layout inconsistent with `into` (and similar libraries/specs) HOT 2
- Generic numeric types? HOT 7
- Example? HOT 7
- Implementations for Pod, Zeroable HOT 1
- Default impl? HOT 11
- Unique Conversion Trait HOT 8
- Add iterop types for const-generic-dimensional types
- casting between generic number types HOT 7
- Setup github actions HOT 1
- Publish a new Version HOT 1
- Update math libraries to support `IntoMint`
- MSRV
- From<Vector2> for (f32, f32) and friends HOT 7
- Switch to const generics HOT 5
- Implement `Add` and `Sub` HOT 1
- derive(defmt::Format) for embedded systems HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mint.