5 ms·
I would love to use Rust more, and have enjoyed working with it on some toy projects, but the last time I looked there wasn't a super solid general purpose math
by santaclaus 11y ago
I would love to use Rust more, and have enjoyed working with it on some toy projects, but the last time I looked there wasn't a super solid general purpose math library. Is there anything out there for Rust that is of similar scope to C++'s Eigen or Python's NumPy+SciPy? What about SSE/AVX intrinsics from Rust?
- NotRustAgain 11y agoI really wanted to use Rust for numerical/scientific computing tasks, but it's kind of miserable for it. I didn't get hung up on the ownership things that all of the Rust zealots talk about (although I think explicit lifetimes are needlessly complicated). I got hung up trying to implement simple things like complex numbers and matrices in a way that was generic and usable. I'm sure some Rust fanboy will argue that Rust has operator overloading through traits, so I'll challenge anyone to make a workable implementation such that zA and 2.0B works in the following generics: let z = Complex<f64>::new(1.0, 2.0); let A = Matrix<f64>::ident(10, 10); let B : Matrix<Complex<f64>> = z*A; let C : Matrix<Complex<f64>> = 2.0*B; If Rust can't do scalar multiplication or real to complex conversions, it's really not usable for what Eigen or Numpy can do. Try defining the Mul trait generically for those multiplication operators, and you'll see what I mean. (yes, I know there are some syntax errors in the type declarations above - It's my opinion Rust got that wrong too...) Supposedly this kind of thing will eventually be possible with the recent "specialization" changes, but I haven't seen anything that allows operators to work as above... ps: Last I looked, there was fledgling support for SIMD on the horizon... LLVM supports that, so it could happen.
- pcwalton 11y agoThis is essentially a complaint that Rust went with strongly-typed generics like every statically-typed, non-C++, non-D language instead of untyped templates like C++ and D. I think that the difficulty of reasoning about template expansion type errors, the complexity of SFINAE, and the consequences for name resolution like ADL make templates not worth the added expressive power for Rust, especially when the features needed to support your use case can be added in the strongly-typed setting eventually.
- wtetzner 11y ago> This is essentially a complaint that Rust went with strongly-typed generics It could also be a complaint about how operators are implemented, e.g. in Scala they're just methods (no need for a special trait). That's not to say I don't think Rust made the right choice, but Scala went with strongly-typed generics, and can allow implementing the asymmetric multiplication operators.
- pcwalton 11y agoIf operators are just specially named methods, then with strongly-typed generics you can't write generic functions that work on anything that (for example) implements the + operator, because traits (concepts) have to have a specific signature.
- wtetzner 11y agoYes, you're right. The only way I can think of to handle it (in Scala, I suppose you can't do it in Rust) would be via implicit parameters. You would basically have a Times trait, and a TimesOp trait. trait TimesOp[L,R,O] { def times(L left, R right): O } object TimesOps { implicit object ScalarMatrixTimesOp[S] extends TimesOp[S,Matrix[S],Matrix[S]] { override def times(S left, Matrix[S] right): Matrix[S] = { ... } } } trait Times { self: L => def *[R,O](R right, implicit timesOp: TimesOp[L,R,O]): O = timesOp.times(this, right) } I'm sure I got something wrong here, but I think the basic idea works. In any case, it goes to show that getting this behavior in a language with strongly-typed generics is non-trivial.
- lomnakkus 11y agoI don't think that's quite right... ISTM that it's more about lack of multi-parameter type classes/traits[1] (+ specialization, I guess) and the fact that it went with the traditional non-symmetrical dot-based notation for dispatch... which means that the first "trait-parameter" would always be "privileged" (at least syntactically). [1] At least I don't think it has those yet, right?