On 07/24/2014 06:46 PM, Gregor Cramer wrote:
1. Overloading is not supported (even the archaic C++ is providing this).

I should note that Rust provides a limited form of overloading via the trait-double dispatch trick:

trait PowImpl<Res>
{
        fn pow(self, exp: uint) -> Res;
}

fn pow<Res, T: PowImpl<Res>>(t: T, exp: uint) -> Res
{
    t.pow(exp)
}

impl PowImpl<int> for int
{
        fn pow(self, exp: uint) -> int
        {
                ...
        }
}

impl<'l> PowImpl<BigInt> for &'l BigInt
{
        fn pow(self, exp: uint) -> BigInt
        {
                ...
        }
}

Note that this is not suitable for generic code, which is kind of an under-appreciated problem. Currently Rust places running generic code above writing efficient code, which is not a trade-off it should be making imo. In my matrix library I opted for making my types useless for generic code in the quest for efficiency, and I find it unfortunate that I had to do that.


2. The footprint 'base: T' is not 100% suitable, for big integers the
function

definition

fn pow(base: &BigInt, mut exp: uint) -> BigInt

would be more appropriate, because the argument 'base' needs not to be

modified (or reassigned), and a call by reference (avoiding a superfluous

memory allocation) is more efficient in this case.


Yes, I concur on most of these points and I've brought up some related points before. The operator overloading technique used by Rust is antithetical to efficient generic code. The core numeric traits and functions are currently designed only with built-in types in mind, causing BigInt (and others, e.g. matrices) to suffer. I don't know how to fix these things, but perhaps auto-ref and ad-hoc operator overloading (it works for Haskell, why not for Rust?) would be part of the solution. Ultimately, I suspect that function overloading (the Rust trait double-dispatch trick above may be sufficient with auto-ref) will be of critical importance. This problem is very under-appreciated and I hope this aspect of the language is not stabilized by 1.0.

If the relevant operator overload is removed from BigInt, then one temporary solution will emerge: you won't be able to call this pow function at all, and will be forced to call a specialized version. As long as the core is designed for built-in types only, BigInt should stop pretending to be one. I think this is what should be done in the interim.

-SL

_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to