Re: [rust-dev] impl num::Zero and std::ops::Add error
at some point, I conveniently used num::one and num::zero to write expressions in template code. here's a simple example. pub fn powerCosHemispherePdfW(aNormal: &Vec3x, aDirection: &Vec3x, aPower:T ) -> T { let cosTheta = num::max(num::zero::(), Vec3x::dot(aNormal, aDirection)); return (aPower + num::one::()) * num::pow(cosTheta, aPower) * (num::cast::(0.5) * num::Real::frac_1_pi()); } I already find using num::zero in that code not ideal regarding to readability, so renaming additiveIdentity even worse. it is very possible that the code above could be re-written in a better way and I would love to find out how. perhaps there is enough room in rust for both simple traits such as zero and one, and for more advanced mathematical traits such as additive identity and multiplicative identity. Rémi On Fri, Apr 11, 2014 at 8:57 PM, Yegor Wienski wrote: > All of the mathematicians I know won’t bother to read them this way (if > there’s no ambiguity, of course). Long names can be good in scientific > papers, but in practice one should be a complete boring jerk to name them > like this. > It would be a pain typing even the word ‘identity’ in a game engine over > and over. I write for Unity3d, and Vector3.zero and Vector3.one are just > fine, but Quaternion.identity makes code look too verbose, so I `static > readonly QI = Quaternion.identity` it. > Long names require special training to get comfortable with them, and > sometimes it even looks like a superpower to me. > > > On 10 Apr 2014, at 19:07, Tommi wrote: > > Actually, I'd like to reiterate my original view that num::Zero should be > renamed to AdditiveIdentity (bear with me) based on the fact that when > mathematicians use the symbol 0 to denote additive identity, the symbol 0 > is not read "zero", but as "additive identity". > > All the reasoning above applies to renaming num::One to > MultiplicativeIdentity as well (as it pertains to symbol 1 denoting > multiplicative identity). > > If those names are too long, the shortened AddIdentity and MulIdentity > could be used instead. > > > On 10 Apr 2014, at 00:06, Tommi Tissari wrote: > > On 09 Apr 2014, at 23:42, Kevin Ballard wrote: > > The number 0 is the additive identity for numbers. But informally, the > additive identity for other things can be called "zero" without problem. > > > Ok, so it seems. From > http://en.m.wikipedia.org/wiki/Identity_(mathematics) > > The number *0* is the *additive identity* (identity element for the > binary operation of addition) for integers, real numbers, and complex > numbers. For every number *a*, including 0 itself, > [image: 0 + a = a+0=a\,.] > In a more general context, when a binary operation is denoted with + and > has an identity, this identity is commonly denoted by the symbol 0 (zero) > and called an *additive identity*. > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Rémi Fontan : remifon...@yahoo.fr mobile: +64 21 855 351 93 Otaki Street, Miramar 6022 Wellington, New Zealand ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
All of the mathematicians I know won’t bother to read them this way (if there’s no ambiguity, of course). Long names can be good in scientific papers, but in practice one should be a complete boring jerk to name them like this. It would be a pain typing even the word ‘identity’ in a game engine over and over. I write for Unity3d, and Vector3.zero and Vector3.one are just fine, but Quaternion.identity makes code look too verbose, so I `static readonly QI = Quaternion.identity` it. Long names require special training to get comfortable with them, and sometimes it even looks like a superpower to me. On 10 Apr 2014, at 19:07, Tommi wrote: > Actually, I'd like to reiterate my original view that num::Zero should be > renamed to AdditiveIdentity (bear with me) based on the fact that when > mathematicians use the symbol 0 to denote additive identity, the symbol 0 is > not read "zero", but as "additive identity". > > All the reasoning above applies to renaming num::One to > MultiplicativeIdentity as well (as it pertains to symbol 1 denoting > multiplicative identity). > > If those names are too long, the shortened AddIdentity and MulIdentity could > be used instead. > > > On 10 Apr 2014, at 00:06, Tommi Tissari wrote: > >> On 09 Apr 2014, at 23:42, Kevin Ballard wrote: >> >>> The number 0 is the additive identity for numbers. But informally, the >>> additive identity for other things can be called "zero" without problem. >> >> Ok, so it seems. From >> http://en.m.wikipedia.org/wiki/Identity_(mathematics) >> >> The number 0 is the additive identity (identity element for the binary >> operation of addition) for integers, real numbers, and complex numbers. For >> every number a, including 0 itself, >> >> In a more general context, when a binary operation is denoted with + and has >> an identity, this identity is commonly denoted by the symbol 0 (zero) and >> called an additive identity. >> >> ___ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
Actually, I'd like to reiterate my original view that num::Zero should be renamed to AdditiveIdentity (bear with me) based on the fact that when mathematicians use the symbol 0 to denote additive identity, the symbol 0 is not read "zero", but as "additive identity". All the reasoning above applies to renaming num::One to MultiplicativeIdentity as well (as it pertains to symbol 1 denoting multiplicative identity). If those names are too long, the shortened AddIdentity and MulIdentity could be used instead. > On 10 Apr 2014, at 00:06, Tommi Tissari wrote: > >> On 09 Apr 2014, at 23:42, Kevin Ballard wrote: >> >> The number 0 is the additive identity for numbers. But informally, the >> additive identity for other things can be called "zero" without problem. > > Ok, so it seems. From > http://en.m.wikipedia.org/wiki/Identity_(mathematics) > > The number 0 is the additive identity (identity element for the binary > operation of addition) for integers, real numbers, and complex numbers. For > every number a, including 0 itself, > > > In a more general context, when a binary operation is denoted with + and has > an identity, this identity is commonly denoted by the symbol 0 (zero) and > called an additive identity. > > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
A nice side-effect of using such a trait as a bound to the range argument type A is that the meaning of iter::range(a, b) would become coherent (same regardless of A) and more intuitive: returns a DoubleEndedIterator to all the possible (and valid) values of type A in [a, b) in ascending order. > On 10 Apr 2014, at 09:27, Kevin Ballard wrote: > > On Apr 9, 2014, at 11:25 PM, Tommi Tissari wrote: > >>> On 10 Apr 2014, at 07:55, Corey Richardson wrote: >>> >>> range doesn't return a forward iterator. Range also implements >>> DoubleEndedIterator. >> >> Ok, I didn't realize that. But it still should't require Add when all >> it needs is a way to get to the next and previous values. > > Any such trait for this would really need to be designed expressly for Range, > and then reimplemented for every single numeric type. > > -Kevin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
On Apr 9, 2014, at 11:25 PM, Tommi Tissari wrote: >> On 10 Apr 2014, at 07:55, Corey Richardson wrote: >> >> range doesn't return a forward iterator. Range also implements >> DoubleEndedIterator. > > Ok, I didn't realize that. But it still should't require Add when all > it needs is a way to get to the next and previous values. Any such trait for this would really need to be designed expressly for Range, and then reimplemented for every single numeric type. -Kevin smime.p7s Description: S/MIME cryptographic signature ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
> On 10 Apr 2014, at 07:55, Corey Richardson wrote: > > range doesn't return a forward iterator. Range also implements > DoubleEndedIterator. Ok, I didn't realize that. But it still should't require Add when all it needs is a way to get to the next and previous values. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
> On 10 Apr 2014, at 07:53, Kevin Ballard wrote: > > On Apr 9, 2014, at 9:50 PM, Tommi Tissari wrote: > >>> On 10 Apr 2014, at 00:22, Kevin Ballard wrote: >>> >>> FWIW, my point about range is it relies on One being the number 1, rather >>> than being the multiplicative identity. AFAIK there's nothing special about >>> 1 in a ring outside of its status as a multiplicative identity. Certainly >>> it's not considered some special value for addition. >> >> Another problem with std::iter::range is that it requires too much from its >> argument type A by saying A must implement Add while it only returns a >> forward iterator. >> >> Perhaps, in order to make a more sensible implementation of iter::range, a >> new concept, a trait, is needed to be able to specify that a certain type T >> implements a method 'increment' that modifies a variable of type T from >> value x to value y such that: >> 1) x < y >> 2) there is no valid value z of type T satisfying x < z < y >> >> For integral types there would an implementation of this trait in stdlib >> with 'increment' doing x += 1; >> >> Then, a natural extension to this trait would be a trait that has a method >> 'advance(n: uint)' that would, at constant time, conceptually call the >> 'increment' method n times. >> >> Then there would also be a 'decrement' method for going the other direction. >> >> There probably needs to be some other use cases for this new trait to carry >> its weight though. > > This trait would disallow range(0f32, 10f32) because there are quite a lot of > valid values z of type f32 satisfying 0f32 < z < 1f32. > > -Kevin The trait wouldn't disallow, but it would change the meaning of such range. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
range doesn't return a forward iterator. Range also implements DoubleEndedIterator. On Thu, Apr 10, 2014 at 12:53 AM, Kevin Ballard wrote: > On Apr 9, 2014, at 9:50 PM, Tommi Tissari wrote: > >>> On 10 Apr 2014, at 00:22, Kevin Ballard wrote: >>> >>> FWIW, my point about range is it relies on One being the number 1, rather >>> than being the multiplicative identity. AFAIK there's nothing special about >>> 1 in a ring outside of its status as a multiplicative identity. Certainly >>> it's not considered some special value for addition. >> >> Another problem with std::iter::range is that it requires too much from its >> argument type A by saying A must implement Add while it only returns a >> forward iterator. >> >> Perhaps, in order to make a more sensible implementation of iter::range, a >> new concept, a trait, is needed to be able to specify that a certain type T >> implements a method 'increment' that modifies a variable of type T from >> value x to value y such that: >> 1) x < y >> 2) there is no valid value z of type T satisfying x < z < y >> >> For integral types there would an implementation of this trait in stdlib >> with 'increment' doing x += 1; >> >> Then, a natural extension to this trait would be a trait that has a method >> 'advance(n: uint)' that would, at constant time, conceptually call the >> 'increment' method n times. >> >> Then there would also be a 'decrement' method for going the other direction. >> >> There probably needs to be some other use cases for this new trait to carry >> its weight though. > > This trait would disallow range(0f32, 10f32) because there are quite a lot of > valid values z of type f32 satisfying 0f32 < z < 1f32. > > -Kevin > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
On Apr 9, 2014, at 9:50 PM, Tommi Tissari wrote: >> On 10 Apr 2014, at 00:22, Kevin Ballard wrote: >> >> FWIW, my point about range is it relies on One being the number 1, rather >> than being the multiplicative identity. AFAIK there's nothing special about >> 1 in a ring outside of its status as a multiplicative identity. Certainly >> it's not considered some special value for addition. > > Another problem with std::iter::range is that it requires too much from its > argument type A by saying A must implement Add while it only returns a > forward iterator. > > Perhaps, in order to make a more sensible implementation of iter::range, a > new concept, a trait, is needed to be able to specify that a certain type T > implements a method 'increment' that modifies a variable of type T from value > x to value y such that: > 1) x < y > 2) there is no valid value z of type T satisfying x < z < y > > For integral types there would an implementation of this trait in stdlib with > 'increment' doing x += 1; > > Then, a natural extension to this trait would be a trait that has a method > 'advance(n: uint)' that would, at constant time, conceptually call the > 'increment' method n times. > > Then there would also be a 'decrement' method for going the other direction. > > There probably needs to be some other use cases for this new trait to carry > its weight though. This trait would disallow range(0f32, 10f32) because there are quite a lot of valid values z of type f32 satisfying 0f32 < z < 1f32. -Kevin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
> On 10 Apr 2014, at 00:22, Kevin Ballard wrote: > > FWIW, my point about range is it relies on One being the number 1, rather > than being the multiplicative identity. AFAIK there's nothing special about 1 > in a ring outside of its status as a multiplicative identity. Certainly it's > not considered some special value for addition. Another problem with std::iter::range is that it requires too much from its argument type A by saying A must implement Add while it only returns a forward iterator. Perhaps, in order to make a more sensible implementation of iter::range, a new concept, a trait, is needed to be able to specify that a certain type T implements a method 'increment' that modifies a variable of type T from value x to value y such that: 1) x < y 2) there is no valid value z of type T satisfying x < z < y For integral types there would an implementation of this trait in stdlib with 'increment' doing x += 1; Then, a natural extension to this trait would be a trait that has a method 'advance(n: uint)' that would, at constant time, conceptually call the 'increment' method n times. Then there would also be a 'decrement' method for going the other direction. There probably needs to be some other use cases for this new trait to carry its weight though. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
FWIW, my point about range is it relies on One being the number 1, rather than being the multiplicative identity. AFAIK there's nothing special about 1 in a ring outside of its status as a multiplicative identity. Certainly it's not considered some special value for addition. As an example as to why this usage is weird, range(0f32, 10f32) actually is defined, and will produce [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. Similarly, range(0.5f32, 10f32) is defined and will produce [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]. This is technically a mis-use of One, but it just happens to produce reasonable values. Of course, if you use it on, say, a 2x2 matrix that defines Add, defines One as {{1,0},{0,1}} (the multiplicative identity), and also has some arbitrary definition of Ord, then range() would operate over this matrix and produce very weird results. For example, range(matrix![[1,2],[3,4]], matrix![10,10],[10,10]]) might, depending on the Ord definition, produce [matrix![[1,2],[3,4]], matrix![[2,2],[3,5]], matrix![[3,2],[3,6]], ...]. You can see that this is a nonsensical range (not that I think there is a way to define range for matrices that makes any sense). In any case, my overall point is Zero and One are more practical names than AdditiveIdentity and MultiplicativeIdentity. If we wanted a proper, accurate numeric hierarchy, we'd use the latter. But libstd wants a practical, shallow hierarchy. And there's certainly nothing stopping you from defining a separate libnumerics that provides an accurate mathematica numeric hierarchy (this is probably something that would be useful to have, but libstd doesn't want it because it's really easy to get wrong, e.g. I believe Haskell thinks their numeric hierarchy was a mistake). -Kevin On Apr 9, 2014, at 2:10 PM, Eric Reed wrote: > I think part of the confusion here is that "matrix addition" isn't actually a > binary operator, but rather a family of binary operators parametrized over > the matrix dimensions. There's +<2,2> for 2 x 2 matrices, +<2,3> for 2 x 3 > matrices, etc. Similarly, the "zero matrix" is actually parametrized over > dimensions. 0<2,2> is different from 0<2,3>. For any n,m: + has the > identity 0. If we wanted to properly represent that in Rust, we would > need type level naturals that we could parametrize Matrix over. > > Regarding the range thing, I thought for a minute that it might make sense if > we required Mul+One+Add+Zero to be a ring (which is the intention I think), > but I don't think that's actually true in general for rings (i.e. that 1 is a > generating set of the underlying group). > > > On Wed, Apr 9, 2014 at 1:42 PM, Kevin Ballard wrote: > The number 0 is the additive identity for numbers. But informally, the > additive identity for other things can be called "zero" without problem. > Heck, even the wikipedia page on Additive Identity uses this example for > groups: > > > Let (G, +) be a group and let 0 and 0' in G both denote additive > > identities, so for any g in G, > > > > 0 + g = g = g + 0 and 0' + g = g = g + 0' > > It follows from the above that > > > > (0') = (0') + 0 = 0' + (0) = (0) > > Look at that, an additive identity for something other than a number, and > zero (0) is used to denote this additive identity. > > The only issue comes in when you define addition in multiple different ways > for a single type. Of course, right now I believe compiler bugs prevent you > from actually using multiple implementations of Add<> with different type > parameters for a given type, so this isn't actually a problem right now. And > when that bug is fixed, it's still reasonable to consider Zero to be the > additive identity for any addition where the receiver type is the right-hand > side of the addition. In other words, if you define Add for > Matrix, then the additive identity here is Zero::, not Zero:: Matrix>. > > Regarding "You can't assign a zero to a 2x2 matrix", additive identity does > not require the ability to assign. And this is only a problem when > considering addition between disparate types. If you consider matrix addition > (e.g. 2x2 matrix + 2x2 matrix) then you certainly can assign the additive > identity back to one of the matrix values. > > let m: Matrix = Zero::zero(); > > looks fine to me. It produces a matrix m that, when added to any other Matrix > m', produces the same matrix m'. This is presumably a Matrix where every > element is 0. But again, this only makes sense if you've actually defined > Add for Matrix. > > Regardless, we've already made the decision not to go down numeric type > hierarchy hell. We're trying to keep a reasonable simple numeric hierarchy. > And part of that means using straightforward "lay-person" terms instead of > perhaps more precise mathematical names. As such, we have std::num::Zero as > the additive identity and std::num::One as the multiplicative identity. > > If you really want to complain about something,
Re: [rust-dev] impl num::Zero and std::ops::Add error
I think part of the confusion here is that "matrix addition" isn't actually a binary operator, but rather a family of binary operators parametrized over the matrix dimensions. There's +<2,2> for 2 x 2 matrices, +<2,3> for 2 x 3 matrices, etc. Similarly, the "zero matrix" is actually parametrized over dimensions. 0<2,2> is different from 0<2,3>. For any n,m: + has the identity 0. If we wanted to properly represent that in Rust, we would need type level naturals that we could parametrize Matrix over. Regarding the range thing, I thought for a minute that it might make sense if we required Mul+One+Add+Zero to be a ring (which is the intention I think), but I don't think that's actually true in general for rings (i.e. that 1 is a generating set of the underlying group). On Wed, Apr 9, 2014 at 1:42 PM, Kevin Ballard wrote: > The number 0 is the additive identity for numbers. But informally, the > additive identity for other things can be called "zero" without problem. > Heck, even the wikipedia page on Additive Identity uses this example for > groups: > > > Let (G, +) be a group and let 0 and 0' in G both denote additive > identities, so for any g in G, > > > > 0 + g = g = g + 0 and 0' + g = g = g + 0' > > It follows from the above that > > > > (0') = (0') + 0 = 0' + (0) = (0) > > Look at that, an additive identity for something other than a number, and > zero (0) is used to denote this additive identity. > > The only issue comes in when you define addition in multiple different > ways for a single type. Of course, right now I believe compiler bugs > prevent you from actually using multiple implementations of Add<> with > different type parameters for a given type, so this isn't actually a > problem right now. And when that bug is fixed, it's still reasonable to > consider Zero to be the additive identity for any addition where the > receiver type is the right-hand side of the addition. In other words, if > you define Add for Matrix, then the additive identity here is > Zero::, not Zero::. > > Regarding "You can't assign a zero to a 2x2 matrix", additive identity > does not require the ability to assign. And this is only a problem when > considering addition between disparate types. If you consider matrix > addition (e.g. 2x2 matrix + 2x2 matrix) then you certainly can assign the > additive identity back to one of the matrix values. > > let m: Matrix = Zero::zero(); > > looks fine to me. It produces a matrix m that, when added to any other > Matrix m', produces the same matrix m'. This is presumably a Matrix where > every element is 0. But again, this only makes sense if you've actually > defined Add for Matrix. > > Regardless, we've already made the decision not to go down numeric type > hierarchy hell. We're trying to keep a reasonable simple numeric hierarchy. > And part of that means using straightforward "lay-person" terms instead of > perhaps more precise mathematical names. As such, we have std::num::Zero as > the additive identity and std::num::One as the multiplicative identity. > > If you really want to complain about something, complain about > std::num::One being used for things other than multiplicative identity, > e.g. std::iter::range() uses Add and One to produce the next value in the > range. > > -Kevin > > On Apr 9, 2014, at 1:25 PM, Tommi Tissari wrote: > > >> On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > >> > >> Why? Zero is the additive identity. > > > > Zero is _an_ additive identity for numbers, but not for vectors or > matrices. > > > > use std::slice::Items; > > use std::iter::RandomAccessIterator; > > use std::num::Zero; > > > > Items is a RandomAccessIterator, but a RandomAccessIterator is not an > Items. 0 is an additive identity, but an additive identity is not 0. You > can't assign a zero to a 2x2 matrix, and therefore this trait is > incorrectly named. The following just looks wrong: > > > > let m: Matrix = Zero::zero(); > > > >> AdditiveIdentity is the only reasonable alternative, but that's a > mouthful of a name and I think changing the name to this would be more > confusing. > > > > Naming a trait something that it's not is even more confusing. I don't > think we should give an incorrect name to this trait on the grounds of the > correct name being longer. Just look at RandomAccessIterator. > > > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
> On 09 Apr 2014, at 23:42, Kevin Ballard wrote: > > The number 0 is the additive identity for numbers. But informally, the > additive identity for other things can be called "zero" without problem. Ok, so it seems. From http://en.m.wikipedia.org/wiki/Identity_(mathematics) The number 0 is the additive identity (identity element for the binary operation of addition) for integers, real numbers, and complex numbers. For every number a, including 0 itself, In a more general context, when a binary operation is denoted with + and has an identity, this identity is commonly denoted by the symbol 0 (zero) and called an additive identity. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
The number 0 is the additive identity for numbers. But informally, the additive identity for other things can be called "zero" without problem. Heck, even the wikipedia page on Additive Identity uses this example for groups: > Let (G, +) be a group and let 0 and 0' in G both denote additive identities, > so for any g in G, > > 0 + g = g = g + 0 and 0' + g = g = g + 0' > It follows from the above that > > (0') = (0') + 0 = 0' + (0) = (0) Look at that, an additive identity for something other than a number, and zero (0) is used to denote this additive identity. The only issue comes in when you define addition in multiple different ways for a single type. Of course, right now I believe compiler bugs prevent you from actually using multiple implementations of Add<> with different type parameters for a given type, so this isn't actually a problem right now. And when that bug is fixed, it's still reasonable to consider Zero to be the additive identity for any addition where the receiver type is the right-hand side of the addition. In other words, if you define Add for Matrix, then the additive identity here is Zero::, not Zero::. Regarding "You can't assign a zero to a 2x2 matrix", additive identity does not require the ability to assign. And this is only a problem when considering addition between disparate types. If you consider matrix addition (e.g. 2x2 matrix + 2x2 matrix) then you certainly can assign the additive identity back to one of the matrix values. let m: Matrix = Zero::zero(); looks fine to me. It produces a matrix m that, when added to any other Matrix m', produces the same matrix m'. This is presumably a Matrix where every element is 0. But again, this only makes sense if you've actually defined Add for Matrix. Regardless, we've already made the decision not to go down numeric type hierarchy hell. We're trying to keep a reasonable simple numeric hierarchy. And part of that means using straightforward "lay-person" terms instead of perhaps more precise mathematical names. As such, we have std::num::Zero as the additive identity and std::num::One as the multiplicative identity. If you really want to complain about something, complain about std::num::One being used for things other than multiplicative identity, e.g. std::iter::range() uses Add and One to produce the next value in the range. -Kevin On Apr 9, 2014, at 1:25 PM, Tommi Tissari wrote: >> On 09 Apr 2014, at 20:46, Kevin Ballard wrote: >> >> Why? Zero is the additive identity. > > Zero is _an_ additive identity for numbers, but not for vectors or matrices. > > use std::slice::Items; > use std::iter::RandomAccessIterator; > use std::num::Zero; > > Items is a RandomAccessIterator, but a RandomAccessIterator is not an Items. > 0 is an additive identity, but an additive identity is not 0. You can't > assign a zero to a 2x2 matrix, and therefore this trait is incorrectly named. > The following just looks wrong: > > let m: Matrix = Zero::zero(); > >> AdditiveIdentity is the only reasonable alternative, but that's a mouthful >> of a name and I think changing the name to this would be more confusing. > > Naming a trait something that it's not is even more confusing. I don't think > we should give an incorrect name to this trait on the grounds of the correct > name being longer. Just look at RandomAccessIterator. > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
Which is distinct from http://en.wikipedia.org/wiki/Identity_matrix On Apr 9, 2014 4:31 PM, "Nick Ward" wrote: > http://en.wikipedia.org/wiki/Zero_matrix > On 9 Apr 2014 21:26, "Tommi Tissari" wrote: > >> > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: >> > >> > Why? Zero is the additive identity. >> >> Zero is _an_ additive identity for numbers, but not for vectors or >> matrices. >> >> use std::slice::Items; >> use std::iter::RandomAccessIterator; >> use std::num::Zero; >> >> Items is a RandomAccessIterator, but a RandomAccessIterator is not an >> Items. 0 is an additive identity, but an additive identity is not 0. You >> can't assign a zero to a 2x2 matrix, and therefore this trait is >> incorrectly named. The following just looks wrong: >> >> let m: Matrix = Zero::zero(); >> >> > AdditiveIdentity is the only reasonable alternative, but that's a >> mouthful of a name and I think changing the name to this would be more >> confusing. >> >> Naming a trait something that it's not is even more confusing. I don't >> think we should give an incorrect name to this trait on the grounds of the >> correct name being longer. Just look at RandomAccessIterator. >> >> ___ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
http://en.wikipedia.org/wiki/Zero_matrix On 9 Apr 2014 21:26, "Tommi Tissari" wrote: > > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > > > Why? Zero is the additive identity. > > Zero is _an_ additive identity for numbers, but not for vectors or > matrices. > > use std::slice::Items; > use std::iter::RandomAccessIterator; > use std::num::Zero; > > Items is a RandomAccessIterator, but a RandomAccessIterator is not an > Items. 0 is an additive identity, but an additive identity is not 0. You > can't assign a zero to a 2x2 matrix, and therefore this trait is > incorrectly named. The following just looks wrong: > > let m: Matrix = Zero::zero(); > > > AdditiveIdentity is the only reasonable alternative, but that's a > mouthful of a name and I think changing the name to this would be more > confusing. > > Naming a trait something that it's not is even more confusing. I don't > think we should give an incorrect name to this trait on the grounds of the > correct name being longer. Just look at RandomAccessIterator. > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
> On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > Why? Zero is the additive identity. Zero is _an_ additive identity for numbers, but not for vectors or matrices. use std::slice::Items; use std::iter::RandomAccessIterator; use std::num::Zero; Items is a RandomAccessIterator, but a RandomAccessIterator is not an Items. 0 is an additive identity, but an additive identity is not 0. You can't assign a zero to a 2x2 matrix, and therefore this trait is incorrectly named. The following just looks wrong: let m: Matrix = Zero::zero(); > AdditiveIdentity is the only reasonable alternative, but that's a mouthful of > a name and I think changing the name to this would be more confusing. Naming a trait something that it's not is even more confusing. I don't think we should give an incorrect name to this trait on the grounds of the correct name being longer. Just look at RandomAccessIterator. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
If you implement Add on a type, then you should implement Zero to specify the identity of the + operation on that type. If you simply want to specify a default value, then you should implement Default. On Apr 9, 2014 11:25 AM, "Tommi Tissari" wrote: > > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > > > For reference, the Zero trait lives in std::num, which should be a good > indication that this is a property of numeric types. > > Am I not supposed to use std::num::Zero for defining things like zero > vector or zero matrix? Those are neither numbers nor zeroes. > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
> On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > For reference, the Zero trait lives in std::num, which should be a good > indication that this is a property of numeric types. Am I not supposed to use std::num::Zero for defining things like zero vector or zero matrix? Those are neither numbers nor zeroes. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
In addition, mathematicians typically use the symbol '0' to refer to the additive identity of a ring anyway. On Apr 9, 2014 10:47 AM, "Kevin Ballard" wrote: > Why? Zero is the additive identity. It's only bad if you want to denote a > value that contains zeros that doesn't support addition, but that's only > bad because of a misconception that Zero should mean "a default value" when > we have Default for that. For reference, the Zero trait lives in std::num, > which should be a good indication that this is a property of numeric types. > > AdditiveIdentity is the only reasonable alternative, but that's a mouthful > of a name and I think changing the name to this would be more confusing. > Someone who needs a numeric zero isn't going to go looking for > AdditiveIdentity, they're going to look for Zero. > > -Kevin > > On Apr 9, 2014, at 6:29 AM, Liigo Zhuang wrote: > > Zero is a bad name here, it should be renamed or removed > 2014年4月9日 上午1:20于 "Kevin Ballard" 写道: > >> On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: >> >> On 07 Apr 2014, at 08:44, Nicholas Radford >> wrote: >> >> I think the original question was, why does the zero trait require the >> add trait. >> >> If that was the original question, then my answer would be that >> std::num::Zero requires the Add trait because of the way it is >> specified: "Defines an additive identity element for Self". Then the >> question becomes: "why is Zero specified like that?", and I would answer: >> because then you can use it in generic algorithms which require their >> argument(s) to have an additional identity. >> >> >> If you want a zero value for a type that doesn't support addition, >> std::default::Default may be a good choice to use. Semantically, that >> actually returns the "default value" for a type instead of the "zero >> value", but in a type without addition, how do you define "zero value"? >> >> -Kevin >> >> ___ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
Why? Zero is the additive identity. It's only bad if you want to denote a value that contains zeros that doesn't support addition, but that's only bad because of a misconception that Zero should mean "a default value" when we have Default for that. For reference, the Zero trait lives in std::num, which should be a good indication that this is a property of numeric types. AdditiveIdentity is the only reasonable alternative, but that's a mouthful of a name and I think changing the name to this would be more confusing. Someone who needs a numeric zero isn't going to go looking for AdditiveIdentity, they're going to look for Zero. -Kevin On Apr 9, 2014, at 6:29 AM, Liigo Zhuang wrote: > Zero is a bad name here, it should be renamed or removed > > 2014年4月9日 上午1:20于 "Kevin Ballard" 写道: > On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > >> On 07 Apr 2014, at 08:44, Nicholas Radford wrote: >> >>> I think the original question was, why does the zero trait require the add >>> trait. >>> >> If that was the original question, then my answer would be that >> std::num::Zero requires the Add trait because of the way it is specified: >> "Defines an additive identity element for Self". Then the question becomes: >> "why is Zero specified like that?", and I would answer: because then you can >> use it in generic algorithms which require their argument(s) to have an >> additional identity. > > If you want a zero value for a type that doesn't support addition, > std::default::Default may be a good choice to use. Semantically, that > actually returns the "default value" for a type instead of the "zero value", > but in a type without addition, how do you define "zero value"? > > -Kevin > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
Zero is a bad name here, it should be renamed or removed 2014年4月9日 上午1:20于 "Kevin Ballard" 写道: > On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > > On 07 Apr 2014, at 08:44, Nicholas Radford > wrote: > > I think the original question was, why does the zero trait require the add > trait. > > If that was the original question, then my answer would be that > std::num::Zero requires the Add trait because of the way it is specified: > "Defines an additive identity element for Self". Then the question > becomes: "why is Zero specified like that?", and I would answer: because > then you can use it in generic algorithms which require their argument(s) > to have an additional identity. > > > If you want a zero value for a type that doesn't support addition, > std::default::Default may be a good choice to use. Semantically, that > actually returns the "default value" for a type instead of the "zero > value", but in a type without addition, how do you define "zero value"? > > -Kevin > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
The problem and a potential source of confusion is that the trait is named 'Zero' when a more proper name would be 'AdditiveIdentity'. There could be separate trait to indicate zero, but I don't know how much value such a trait would have. Here's the formal definition of additive identity from wikipedia: Let N be a set which is closed under the operation of addition, denoted +. An additive identity for N is any element e such that for any element n in N, e + n = n = n + e Example: The formula is n + 0 = n = 0 + n. That's the reason it doesn't require the Mult trait. > On 09 Apr 2014, at 11:18, Rémi Fontan wrote: > > thanks for all your replies. I understand that zero has a specific meaning to > addition, and as well as multiplication, but for some reason does not require > the mul trait. > > implementing default sounds like a reasonable solution for my case. I > initially wanted to implement zero for my matrix4x4. I haven't implemented > add as I don't think I'm going to be adding matrix so I did not bother. > making default return [0...0] would work as well. > > cheers, > > Rémi > > > >> On Wed, Apr 9, 2014 at 5:20 AM, Kevin Ballard wrote: >>> On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: >>> On 07 Apr 2014, at 08:44, Nicholas Radford wrote: I think the original question was, why does the zero trait require the add trait. >>> If that was the original question, then my answer would be that >>> std::num::Zero requires the Add trait because of the way it is specified: >>> "Defines an additive identity element for Self". Then the question becomes: >>> "why is Zero specified like that?", and I would answer: because then you >>> can use it in generic algorithms which require their argument(s) to have an >>> additional identity. >> >> If you want a zero value for a type that doesn't support addition, >> std::default::Default may be a good choice to use. Semantically, that >> actually returns the "default value" for a type instead of the "zero value", >> but in a type without addition, how do you define "zero value"? >> >> -Kevin >> >> ___ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > > -- > Rémi Fontan : remifon...@yahoo.fr > mobile: +64 21 855 351 > 93 Otaki Street, Miramar 6022 > Wellington, New Zealand ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
thanks for all your replies. I understand that zero has a specific meaning to addition, and as well as multiplication, but for some reason does not require the mul trait. implementing default sounds like a reasonable solution for my case. I initially wanted to implement zero for my matrix4x4. I haven't implemented add as I don't think I'm going to be adding matrix so I did not bother. making default return [0...0] would work as well. cheers, Rémi On Wed, Apr 9, 2014 at 5:20 AM, Kevin Ballard wrote: > On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > > On 07 Apr 2014, at 08:44, Nicholas Radford > wrote: > > I think the original question was, why does the zero trait require the add > trait. > > If that was the original question, then my answer would be that > std::num::Zero requires the Add trait because of the way it is specified: > "Defines an additive identity element for Self". Then the question > becomes: "why is Zero specified like that?", and I would answer: because > then you can use it in generic algorithms which require their argument(s) > to have an additional identity. > > > If you want a zero value for a type that doesn't support addition, > std::default::Default may be a good choice to use. Semantically, that > actually returns the "default value" for a type instead of the "zero > value", but in a type without addition, how do you define "zero value"? > > -Kevin > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Rémi Fontan : remifon...@yahoo.fr mobile: +64 21 855 351 93 Otaki Street, Miramar 6022 Wellington, New Zealand ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > On 07 Apr 2014, at 08:44, Nicholas Radford wrote: > >> I think the original question was, why does the zero trait require the add >> trait. >> > If that was the original question, then my answer would be that > std::num::Zero requires the Add trait because of the way it is specified: > "Defines an additive identity element for Self". Then the question becomes: > "why is Zero specified like that?", and I would answer: because then you can > use it in generic algorithms which require their argument(s) to have an > additional identity. If you want a zero value for a type that doesn't support addition, std::default::Default may be a good choice to use. Semantically, that actually returns the "default value" for a type instead of the "zero value", but in a type without addition, how do you define "zero value"? -Kevin___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
> On 07 Apr 2014, at 08:44, Nicholas Radford wrote: > > I think the original question was, why does the zero trait require the add > trait. > If that was the original question, then my answer would be that std::num::Zero requires the Add trait because of the way it is specified: "Defines an additive identity element for Self". Then the question becomes: "why is Zero specified like that?", and I would answer: because then you can use it in generic algorithms which require their argument(s) to have an additional identity. > And it's a valid question. What does saying a value can have a zero value > have to do with adding numbers. > > In other words, it is possible for something to have a zero value without > requiring addition, so why does the Zero trait not reflect this. > >> On 6 Apr 2014 12:29, "Tommi" wrote: >> The tutorial (17.7) says the following: >> "We can write a trait declaration that inherits from other traits, called >> supertraits. Types that implement a trait must also implement its >> supertraits. >> >> Since num::Zero inherits from Add, you must implement it (the >> supertrait) also. >> >>> On 2014-06-04, at 11:25, Rémi Fontan wrote: >>> >>> Hi, >>> >>> when compiling following code I get following error: >>> use std::num; >>> struct vec2d { a:f32, b:f32 } >>> impl num::Zero for vec2d { >>> fn zero() -> vec2d { >>> vec2d{a:0.0, b:0.0} >>> } >>> >>> fn is_zero(&self) -> bool { >>> self.a==0.0 && self.b==0.0 >>> } >>> } >>> >>> >>> >>> test.rs:4:1: 12:2 error: failed to find an implementation of trait >>> std::ops::Add for vec2d >>> test.rs:4 impl num::Zero for vec2d { >>> test.rs:5 fn zero() -> vec2d { >>> test.rs:6 vec2d{a:0.0, b:0.0} >>> test.rs:7 } >>> test.rs:8 >>> test.rs:9 fn is_zero(&self) -> bool { >>> >>> >>> Would you know why the Add trait seems to be a requirement for implementing >>> the zero trait. >>> >>> cheers, >>> >>> Rémi >>> >>> >>> ___ >>> Rust-dev mailing list >>> Rust-dev@mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >> >> >> ___ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
The tutorial (17.7) says the following: "We can write a trait declaration that inherits from other traits, called supertraits. Types that implement a trait must also implement its supertraits. Since num::Zero inherits from Add, you must implement it (the supertrait) also. On 2014-06-04, at 11:25, Rémi Fontan wrote: > Hi, > > when compiling following code I get following error: > use std::num; > struct vec2d { a:f32, b:f32 } > impl num::Zero for vec2d { > fn zero() -> vec2d { > vec2d{a:0.0, b:0.0} > } > > fn is_zero(&self) -> bool { > self.a==0.0 && self.b==0.0 > } > } > > > > test.rs:4:1: 12:2 error: failed to find an implementation of trait > std::ops::Add for vec2d > test.rs:4 impl num::Zero for vec2d { > test.rs:5 fn zero() -> vec2d { > test.rs:6 vec2d{a:0.0, b:0.0} > test.rs:7 } > test.rs:8 > test.rs:9 fn is_zero(&self) -> bool { > > > Would you know why the Add trait seems to be a requirement for implementing > the zero trait. > > cheers, > > Rémi > > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev