Revise `std::num::Float`


#1

What do you think about extracting math functions from Float into a different traits. Currently Float is pretty big and most of functions implemented there is just implementation of cmath. Also, according to doc, some of them has different meaning than “pure math” equivalents (signum or is_positive/negative).

Also it will provide way to utilize some of functions between Int and Float (i. e. there is no max/min implementation for Int).

As addition I would think about using Float as base for trigonometric functions. IMHO all languages do this that way and all of them do it wrong. There should be Angle enum that looks like:

enum Angle<T> {
    Rad(T),
    Deg(T),
    Grad(T)
}

With respectful method implemented on them. This will remove ambiguity on measurement units.

Also we should think about adding Num trait that will implement shared methods between Float and Int like:

  • min/max
  • zero
  • one
  • min/max_value
  • signum
  • is_positive/negative

It could be helpful (especially when we rethink some other traits relations) when implementing, i.e. interval arithmetic, complex numbers and other algebraic oddities that has similar properties as numbers.


#2

Have you read the num-reform RFC: https://github.com/rust-lang/rfcs/blob/master/text/0369-num-reform.md

and its discussion: https://github.com/rust-lang/rfcs/pull/369

?

This is what specified the current API.


#3

A well-typed angle measurement is a good idea, but I think unifying the representation is more efficient:

// this is just a rough sketch. An angle is a wrapper around an internal storage of a value in radians.
struct Angle<F>(F);

impl<F> Angle<F> for F: Float {
    fn radians(x: F) -> Self { Angle(x) }
    fn degrees(d: F) -> Self { Angle::radians(d * Float::pi() / 180.) }  /* do the right cast here etc */
}

#4

I was looking for that but I cannot found it. My bad.

According to topic, IMHO that RFC was step backwards as maybe it provided smaller set of traits but also it limited flexibility of code. There was said that it is hard to find examples of functions that are common for floats and integers. I.e. polynomials or linear algebra and PistonDevelopers/image is example where Zero, One and max_value neded to be reimplemented to write generic code.

For now Float looks like a god-trait that do everything. I would vote up for resplitting it into smaller, more reusable pieces. It would also make possible to implement some of this traits to SIMD vectors.


#5

Additional “pros” when moving math functions from Float to, i.e. Math trait:

The newcomers from other languages could still use “oldskul” syntax, i.e.: Math::sin(0.0) and at the same time, “proper” Rust syntax (0.0.sin()) would still work.

Win - Win