Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does it make sense to modify in-place AND return a copy?

Note: I'm tagging this Python and C++ because I've seen examples in both, but the question is language-agnostic.

A function or class method that modifies an object has two choices: modify the data directly in the object in question, or create a new copy and return it while leaving the original untouched. Generally you can tell which is which by looking at what's returned from the function.

Occasionally you will find a function that tries to do both, modify the original object and then return a copy or reference to that object. Is there ever a case where this provides any advantage over doing only one or the other?

I've seen the example of the Fluent Interface or Method Chaining that relies on returning a reference to the object, but that seems like a special case that should be obvious in context.

My first bad example comes straight from the Python documentation and illustrates the problem of mutable default parameters. To me this example is unrealistic: if the function modifies its parameter then it doesn't make sense to have a default, and if it returns a copy then the copy should be made before any modifications take place. The problem only exists because it tries to do both.

def f(a, L=[]):
    L.append(a)
    return L

The second example comes from Microsoft C++ in the CStringT::MakeUpper function. The documentation says this about the return value:

Returns a copy of the string but in all uppercase characters.

This leads one to expect that the original remains unchanged. Part of the problem is that the documentation is misleading, if you look at the prototype you find that it's returning a reference to the string. You don't notice this unless you look closely, and assigning the result to a new string compiles with no error. The surprise comes later.

like image 817
Mark Ransom Avatar asked Oct 09 '12 22:10

Mark Ransom


People also ask

What does modifying place mean?

in-place modification means change the value in a memory region, while not-in-place assignment creates a new memory region.

Can a Python function modify argument?

If you pass the object as an argument to a function, then its attributes can be modified in place.

What does in place mean Python?

Definition - In-place operation is an operation that changes directly the content of a given linear algebra, vector, matrices(Tensor) without making a copy. The operators which helps to do the operation is called in-place operator.


2 Answers

C++ Example Inc/Dec operator

// Pre-Increment: Create a new object for return and modify self.
myiterator  operator++(int) {myiterator tmp(*this); operator++(); return tmp;}


// Post-Increment: modify self and return a reference
myiterator&  operator++() {/* Do Stuff*/ return *this;}
like image 89
Martin York Avatar answered Oct 13 '22 08:10

Martin York


There are some obvious examples in C++ where you want to modify the object and return a reference:

  1. Assignment:

    T & T::operator=(T && rhs)
    {
        ptr = rhs.ptr;
        rhs.ptr = nullptr;
        return *this;
    }
    

    This one modifies both the object itself and the argument, and it returns a reference to itself. This way you can write a = b = c;.

  2. IOStreams:

    std::ostream & operator<<(std::ostream & os, T const & t)
    {
        os << t->ptr;
        return os;
    }
    

    Again, this allows chaining of operations, std::cout << t1 << t2 << t3;, or the typical "extract and check" if (std::cin >> n) { /* ... */ }.

Basically, returning a reference to one of the input objects always serves to either chain calls or to evaluate the resulting state in some form or another, and there are several useful scenarios for this.

On the other hand, modifying an argument and then returning a copy of the object appears to be less useful.

like image 31
Kerrek SB Avatar answered Oct 13 '22 09:10

Kerrek SB