Hi, I am trying to design wrapper around https://github.com/Microsoft/CNTK/blob/release/2.2/Source/CNTKv2LibraryDll/API/CNTKLibrary.h.
I have first version up and running, but I am quite unhappy with the ergonimics (and maybe that the wrapper seems like C++ forced into Rust).
I have functions with signature:
fn plus(x: &Variable, y: &Variable) -> Variable fn times(x: &Variable, y: &Variable) -> Variable
In C++ the Variable class contains couple of
shared_ptrs. Thus Variable type needs to implement Drop, thus cannot implement Copy, but still can be Cloned.
My problem is around ergonomics where composing functions. Current state is like this:
let w = Variable::new(...); let b = Variable::new(...); let x = Variable::new(...); let res = plus(×(&w, &x), &b);
The number of & feels quite high to me.
The question is: can this be fixed? Is any of following signatures better in communicating underlying intent:
fn plus(x: Variable, y: Variable) -> Variable
This would require couple of clones during calls (which I can live with and maybe better communicates the intent), but no & in function composition, which is nice.
fn plus<T: Borrow<Variable>, U: Borrow<Variable>>(x: T, y: U) -> Variable
This can be called either with reference or by value, but I feel, that it hides a lot of stuff and there are hidden implicit traps.
Second question: Since the most API variables are sort equivalents to
Rc<RefCell<T>> is the idiomatic way of passing
Rc<T> to function by value or by reference?