3 ms·
Are Servo and rustc in the Rust documentation? Literate programming of some sort? Maybe you're replying to a different criticism. I've been through the Rust
by civility 10y ago
Are Servo and rustc in the Rust documentation? Literate programming of some sort? Maybe you're replying to a different criticism.
I've been through the Rust Documentation (doc.rust-lang.org) and Rust By Example (rustbyexample.com) several times now, and I have to jump on IRC to get answers to (what I think should be) some pretty simple questions.
- AsyncAwait 10y agoIf you think something important is missing from the docs, please open an issue. Steve Klabnik is very keen on making the documentation as useful as possible.
- civility 10y agoSteve seems like a genuinely helpful guy, but I'm not sure my most recent headache is a documentation problem so much as a deficiency in the std/core library. I was trying to write a generic function that called abs() on some of the arguments. Here's a simplified version: fn simplified_example<T>(a: T, b: T) -> T where T: Copy + PartialOrd { if a.abs() < b.abs() { // some irrelevant math goes here } else { // slightly different math goes here } } I'd like to be able to call this generic function on anything that has a .abs() method. That includes i8, i16, i32, i64, f32, f64, and so on. Is that a shortcoming in documentation or an unfortunate consequence of Abs not being a trait? Several people on IRC recommended the rust-num/num crate, but that has several other deficiencies, and I don't think I should need another crate (unwanted dependency) to call .abs() on f32 or f64. With help, I came up with a workaround, but this was harder than I think it should be. The grandparent poster said: >> the developer community doesn't seem to realize that there's a massive gap between the toy example programs in their documentation and the level of knowledge needed to build something worthwhile. I have to agree with him. The level of Rust-specific knowledge required to get the absolute value of a number/type in a generic function is pretty significant. The example above is just a small part of a library I'm working on and only one example.
- steveklabnik 10y agoWe tried to get a trait hierarchy for numerical right four or five times; it's really hard. So yeah, you have to use num or make your own at the moment. It's true this is less than optimal; it's just not an easy problem. For just abs it should only be a few lines of code to make your own; three for the trait, and five times two for the impls.
- civility 10y ago> We tried to get a trait hierarchy for numerical right four or five times; it's really hard. I'm clearly not an expert in Rust, and as such I realize my opinion isn't worth much, but it seems to me any attempt to build a numerical hierarchy will result in something fragile. Scheme has a well thought out minimal hierarchy, and even without all the complexity from all the fixed sizes I don't like theirs either. However, it's alright because they have dynamic typing as a release valve. C++ templates dodge the problem because they act more like duck typing, and I think I understand why Rust won't go that way. Instead, I think you should abandon the goal of trying to create a hierarchy and just treat each small concept as a trait. Rather than creating Signed for things with a sign, and Float for things that are floating point and so on as in the num crate, create Abs as a small concept in its own. Then anything on which you can call .abs() implements the Abs trait. This includes things which aren't "signed", such as unsigned numbers and complex numbers - all of those have a useful (even if sometimes trivial) definition of .abs() Trying to build a hierarchy reminds me of the stereotypical examples of bad object oriented design - I'm sure you know the cliches where Human derives from Ape, then Mammal, then Animal, etc... A hierarchy is like trying to build a directory tree, but numeric traits are more like labels on your gmail messages. Traits seem more like mixins or interfaces. You'll end up with a lot of one or two method traits, but you'll also allow people to implement those traits for their own types and implement generic functions over those traits. The Float trait is a really good example of why categorization/hierarchy is unlikely to work well - That trait requires methods like .min_value() which don't make sense for complex numbers, but it is also the interface for .sqrt(), .exp(), and .ln() which have very good definitions for complex numbers. The Float trait in the num crate does not allow me to make generic functions over f32 and Complex<f64> if I want to call .exp(). > For just abs it should only be a few lines of code to make your own Yeah, the IRC people helped me find a different workaround, but I agree that I'll just make my own trait instead. However, the .abs() methods already exist on all of the signed built in types and so I'll probably call mine .mag() on a Mag trait to avoid confusion (I'm not sure if there would be a collision/compilation error if I used the same names?). This also allows me to implement Mag for unsigned types which is useful for generic code (for examples L1 norms of vectors). Btw, the docs for i64 have some cut-and-paste errors where they indicate i32 but almost certainly meant i64.