Yes allot of copying is avoided by default when passing arguments to a function 
and with less noise.

However, as my original question in this thread indicates, it is in the body of 
the function that things my get complicated (ex: when using standard containers 
like dequeue of seqs).

I find the rust solution to be quite beautiful:

Argument can be passed by reference (&), by mutable reference (&mut) or by 
value. In the first two cases, no copy is done and in the case of &mut, the 
object passed can be modified (with all the borrowing rules about &mut). But 
when the object is passed by value, there is two options:

1- If the "object" implements the Copy trait, it is copied (like all primitive 
types).

2- If it does not implement the Copy trait, the object is moved, and the 
compiler will forbid using it any further. ex:
    
    
    let v = vec![1, 2, 3];
    let mut vv : Vec<Vec<i32>> = Vec::new();
    vv.push(v);
    println!("{:?}", v);
    
    # generates the following error
    # error[E0382]: use of moved value: `v`
    # --> src/main.rs:6:22
    #  |
    #5 |     vv.push(v);
    #  |             - value moved here
    #6 |     println!("{:?}", v);
    #  |                      ^ value used here after move
    #  |
    #  = note: move occurs because `v` has type `std::vec::Vec<i32>`, which 
does not implement the `Copy` trait
    

Which means that for "big objects", there is NEVER any copy if not explicitly 
stated with a "v.clone()". This enables the compiler to do some nice 
optimizations and make it easier for the developer to think about performances.

In C++, it is less elegant (you have to call std::move explicitly) and moved 
objects can still be accessed. But it still an important tool for optimization.

In Nim, i don't know if there is a way to tell the compiler "hey I don't need 
this values here anymore, take it instead of copying it"

Reply via email to