Can I have math operators that don't move operands?


I'm playing with symbolic math and would like to be able to write code that looks like this:

let x = var('x');
let y = var('y');
let two = num(2);
let sum = x + y;
let twice_x = two * x;

The problem is that math operators move their operands, so the last line would complain about use of a moved value (i.e. x), unless I make math expressions Copy. But math expressions can contain any other math expressions, so I need some type of redirection like Box, Rc or Arc, but those don't allow a Copy implementation.

Is there a way I haven't thought of?


Best, Oliver

The types for Self and Rhs in operator overloading traits can be whatever you want, so you can implement the operators for references. They will always "move" the type, but the moved type can be &Foo.

You will need an owned Output though.

1 Like

If Self is &MathExpr, would I need to write &x + y instead of x + y?

Yes, or &x + &y if you want to use Add<&MathExpr> for &MathExpr.

Have you looked at the rug crate? It is a binding for gmp. It allows you to write efficient expressions with heap-allocated integers and is reasonably ergonomic.

Yes, but of important note is that you can have the following four implementations simultaneously:

Add<&T> for &T
Add<&T> for T
Add<T> for &T
Add<T> for T

As exemplified here.

This is where using a macro could be useful, so that you only write the impl of Add<&T> for &T, and get the macro impls to divert the others to this one.

Keep in mind, though, that taking ownership of a value allows its allocation to be reused. Macros are still helpful when there are multiple, similarly shaped value types.