5 ms·
I'd trade type inference for expressibility (function and operator overloading in particular). But this seems to currently be a heretical opinion.
by lamontcg 2y ago
I'd trade type inference for expressibility (function and operator overloading in particular). But this seems to currently be a heretical opinion.
- Tuna-Fish 2y agoRust took the other road: error[E0277]: cannot add `i64` to `i32` 1i32 + 2i64; ^ no implementation for `i32 + i64` It bothered me at first, there are a lot of explicit annotations for conversions when dealing with mixed precision stuff. But I now feel that it was the exactly correct choice, and not just because it makes inference easier.
- lamontcg 2y agoRust still lets you create your own algorithmic data types so that you can overload traits like Add, Mul, Div and Sub to implement your own e.g. Vector3 class (although I still feel this is too restrictive, but understand why rust chooses not to do that). What Rust blocks in your example there is implicit type conversion/coercion/promotion, and I'm actually okay with that and forcing being much more explicit about type casting. Go is the language that makes your vector classes required to have syntax like v1.VecMult(v2) and v1.ScalarMult(s) because there's no operator overloading at all (even though there's a largely useless baked-in complex number class).
- adamwk 2y agothe rust traits are not overloading though (at least not in the same way as swift), that’s just implementing a trait on a type. I think the distinction is that with traits or protocols you get a lot of expressivity, reducing the need for overloading
- lamontcg 2y agoYou can still create your own vec3 though that implements "<vec3> * <double>" through the Trait... It seems at least superficially equivalent to operator overloading.
- fauigerzigerk 2y agoIt is operator overloading. Traits are just the mechanism to do operator overloading in Rust. But I think what matters in this particular context is that Rust does not support function overloading and this restriction also applies to functions implementing operators. I think this may be why the parent comment claims that it is not really overloading. The meaning of "overloading" is a bit ambiguous here. So for a concrete type vec3 you cannot define both <vec3> * <double> and <vec3> * <vec3>, which makes type inference a lot easier. It also makes Rust operator overloading less expressive.
- yorwba 2y agoYou can define multiple implementations for the Mul trait with different right-hand sides, no problem at all. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f4037fa7e0e0236fa1f226a585150d71 https://play.rust-lang.org/?version=stable&mode=debug&editio...
- fauigerzigerk 2y agoThanks, I didn't know that. In light of this, would you say that there is any sense in which Rust doesn't support the full extent of what is usually called operater overloading?
- lamontcg 2y agoI'm not who responded to you, but I think the important difference from some other languages is you can't define arbitrary operators, but there does seem to be Traits for overloading at least most of the built-in operators.
- Someone 2y agoSwift does that for integers, floats and doubles, too. https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/ https://docs.swift.org/swift-book/documentation/the-swift-pr...: “Conversions between integer and floating-point numeric types must be made explicit: let three = 3 let pointOneFourOneFiveNine = 0.14159 let pi = Double(three) + pointOneFourOneFiveNine // pi equals 3.14159, and is inferred to be of type Double “