4 ms·
Rust's generics have significant limitations, especially when mixing types, and are cumbersome to use. For example try writing even a basic function accepting
by sidlls 10y ago
Rust's generics have significant limitations, especially when mixing types, and are cumbersome to use.
For example try writing even a basic function accepting two scalars of type T and U and performing arithmetic on them. The way the Rust compiler works it isn't possible without specifying various bounds on the traits (which I appreciate, actually, for explicitness). And even then there are limitations around casting that require non-trivial workarounds (it is ridiculous, frankly, that the num crate isn't in the standard library, but that crate has its own problems).
And there is no specialization, which is a severe limitation.
Can't disagree with your comments re: python.
- pcwalton 10y ago> The way the Rust compiler works it isn't possible without specifying various bounds on the traits. That's a feature! It works the same way in every language other than C++ or D that implements generics. I much prefer explicitly typed generics to untyped generics as in C++. Not only are the error messages far more comprehensible, but it lets us avoid having to introduce confusing name resolution rules like ADL. > And there is no specialization, which is a severe limitation. There is now [1]. [1]: https://github.com/rust-lang/rust/pull/30652 https://github.com/rust-lang/rust/pull/30652
- sidlls 10y agoWell "the same way" is pretty broad. Generics in C++ are too loose and I edited my comment to reflect that I appreciate the explicitness required. That doesn't mean it couldn't be revisited for usability. Also, huzzah for specialization. I'll try that out asap. Thanks for the heads up.
- pjmlp 10y agoNot for much longer I hope, and we already have concepts in gcc 6.0. Just wait for C++20 and STLv2, you will also get that explicitness everywhere with concepts.
- dbaupp 10y agoThis isn't wrong, but it seems to be putting the cart before the horse: even with limitations, having generics is still an improvement over not having them, in terms of one's ability to build type-safe abstractions (i.e. Rust would be a far weaker language without them). For instance, one can write a complicated lock-free data structure that works with any type T, doing the effort to optimise the atomic orderings and avoid leaks (etc.), all without forcing dynamic type casts or unnecessary allocations on downstream users. > The way the Rust compiler works it isn't possible without specifying various bounds on the traits. This is an explicit choice: C++-style check-at-use-site results in some seriously ridiculous error messages, and there's no boundary between implementation and signature, meaning a change to some small detail (and even syntax, in C++) in the implementation can accidentally cause downstream code to fail to compile. It is definitely annoying some times, but Rust, and most other languages with some sort of templates/generics, thinks the benefits outweigh the cost. > And there is no specialization, which is a severe limitation. Indeed, it is a limitation that the team recognises and is working on: https://github.com/rust-lang/rust/issues/31844 https://github.com/rust-lang/rust/issues/31844 (Parts of which are already available in the nightly releases.)
- Retra 10y agoThe num crate is an open problem. There's a lot of contention around what it is supposed to support. Mathematicians, scientists, HPC programmers, prototyping programmers, embedded system programmers, pointer-arithmetic-doing programmers... they all want something different from a number crate. That's why it is not in the std library: there's no agreement on what it should do, and iterating toward perfection in the standard library will introduce a huge amount of churn and breakage. (And if you try to avoid churn and breakage, you're hamstrung by the current implementation to a num crate that suits nobodies needs.)
- Manishearth 10y agoThough if you want to be polymorphic over "adding things" you can just bound on Add :) If you want to be more restrictive over what you want to bound over then the Num crate comes into play.
- sidlls 10y agoYou make an excellent point. I fall into more than one of the buckets you list, and it's definitely the case that there is unlikely a "one size fits all" solution here. However I just have this sense that there is an intersection of basic functionality for using "number types" that neither Rust nor the num crate really supports terribly well. Maybe I'll change my mind as I use it to build out some projects.
- Animats 10y agoThat's always hard. I was involved in the arguments over this for Go. Most languages today have multidimensional array support inferior to FORTRAN. This is not only embarrassing, it's why some heavy number-crunching is still done in FORTRAN. Some people want nice, simple, dense multidimensional arrays. Some want the ability to extract a square section from an array as a subarray. Some want that for N dimensions. Some don't want the overhead for that generality slowing down their matrix multiply. Some are content with arrays of arrays. Some want ragged arrays (rows not the same length). Some want arrays in a format a GPU can use. Passing the buck to each package, though, results in recopying arrays as matrices move from a function in one package to a function in another. One reason people use MATLAB, FORTRAN, and Python's NumPy is that they at least have a standard representation and matrix functions interoperate. I'd argue for supporting dense arrays in the language (and the optimizer) and doing the fancy stuff in packages.