14

Sorry for the generic question. I have searched all over and found so many threads similar to this, however not one that answers my specific question - perhaps because the term I'm looking for doesn't even exist.

A friend of mine is learning programming, JavaScript specifically, and he asked me why this wasn't working:

var a = "Hello World";
a.replace("Hello", "Goodbye");

console.log(a)  // Logs "Hello World"

The reason is because replace does not modify a, as strings are immutable in JavaSript. Becuase it returns a string, you'd need to do something like...

var a = "Hello World";
a = a.replace("Hello", "Goodbye");

console.log(a);  // Logs "Goodbye World"

However, the alternative is a function like JavaScript's reverse(), as it modifies whatever calls it. For example:

var fruits = ["Apples", "Oranges", "Bananas"];
fruits.reverse();

console.log(fruits)  // ["Bananas", "Oranges", "Apples"]

When my friend asked me why his replace wasn't working, I realized I was reaching for a word that I don't know (as far as I'm aware)...

"You have to set the string to "string dot replace", because the replace function is ________."

You don't need to set an array equal to "array dot reverse", because reverse is ________."

I'm familiar with prototype functions though I don't believe that's the word I'm looking for. Can anyone help me fill in these blanks?

4
  • 6
    Maybe the word is "mutator"? as in: You don't need to set an array equal to "array dot reverse", because reverse is a mutator function. I think I've heard that terminology to refer to functions that "mutate" the instance which calls them. But you should probably double-check that somewhere else. Commented Mar 8, 2017 at 19:41
  • Appreciate it! I just did some reading on Mutator Methods and I think that it definitely fits into this conversation quite well. Certainly in the realm of what I'm looking for.
    – Santi
    Commented Mar 8, 2017 at 19:53
  • I am confused: in the title, you ask about a function that modifies the object that called it, but in your examples, you show methods that modify the object they are called on, i.e. the exact opposite of the title. Which of the two is it? Commented Mar 8, 2017 at 20:29
  • Well surely the one explained in 30 lines of detail. I'll modify the title to be accurate, thanks for the heads-up!
    – Santi
    Commented Mar 8, 2017 at 20:32

6 Answers 6

13

The pair of concepts that you are looking for are mutable/immutable parameters and in-place/returning of results.

In your examples:

You have to set the string to "string dot replace", because the replace function operates on a string which, in python, is immutable so the replace function returns a new string.

For a C/C++ programmer this is more familiar as parameters "passed by value", rather than "passed by reference", which makes them immutable and returning the result.

You don't need to set an array equal to "array dot reverse", because reverse operates on an array, which is mutable, so is able to make changes in-place before returning.

In languages such as C/C++ this is known as parameters "passed by reference" i.e. passing the address which, if unmodified by const, allows the function to change, mutate, the contents of that address altering the results in-place before returning.

Of course it is not unusual to have a function that returns results by both mechanisms, e.g. int SomeFn(int p1, int p2, int *ErrCode) can, potentially return results both in the return value and by modifying the contents of ErrCode.

A 3rd Method

For completeness a 3rd mechanism for returning results is by side-effect or global, i.e. modifying file scope, program wide, shared or environmental values. This is generally considered bad news as, unless very well documented, you can only find out what is being changed by careful reading of the code. In languages such as C/C++ this is all too easy to do by having an outer scope variable with a given name, possibly even in another module, and no masking local scope variable of the same name. In Python, while you can read the values of values in outer scopes, unless outer scope values are explicitly set as available to be modified with the global keyword, attempting to modify an outer scope variable automatically creates a local of the same name.

4
  • Ah, I'm familiar with these terms, though I wasn't sure if there was an actual word that describes the function itself. As in, (The reverse function is a _______ function.) That being said, this is nearly an identical response to the one that I ended up giving my friend, so I appreciate your confirmation - though I'm still wondering if there are specific terms. I'm going to let the question stay open for a bit but will certainly accept this as the answer in the event these words simply don't exist.
    – Santi
    Commented Mar 8, 2017 at 19:59
  • 2
    In some languages, such as python, you can also have classes that modify themselves - while in some contexts this "monkey patching" is considered a good thing in many it is considered "self modifying code" and is forbidden. You can also have "evolutionary code" where code fragments are randomly "mutated" and/or combined then are tested and selected for the "best" performance in some manner. Commented Mar 8, 2017 at 20:32
  • -1. Whether strings are mutable or immutable has nothing to do with the function that is operating on it. The function isn't mutable or immutable, and it isn't "returning or in-place". Functions can modify their arguments and still return.
    – mrr
    Commented Mar 14, 2017 at 21:13
  • @MilesRout added that functions that modify in place still return and some C/C++ examples for clarity plus results by side effects for completeness. Commented Mar 15, 2017 at 7:28
5

My preferred way to express it is:

  • The Array reverse method is mutating. It's a mutator. A common special case is a setter.

  • The String replace method is non-mutating. It's not a mutator. If it doesn't modify anything, it's side-effect free. A common special case is a getter.

  • Since JavaScript Strings are immutable, String methods cannot be mutating.

    "Hello World".replace("Hello", "Goodbye");

    should make you uncomfortable. It doesn't modify a string literal. It discards the result. Static code analyzers can sometimes detect such bugs.

  • Since JavaScript Arrays are mutable, Array methods can be mutating. JavaScript tends to use Arrays as local storage bins, easily modified and infrequently copied.
2

Sometimes, when used in the context of pure functional programming, I've heard functions that modify the input value (and therefore are not pure functions) called destructive. I'm not sure if this is the correct term, though.

In your case, you would say:

You have to set the string to "string dot replace", because the replace function is not destructive.

You don't need to set an array equal to "array dot reverse", because reverse is destructive.

1

Perhaps pure is the word you're looking for?

replace() is (or appears to be) pure because it doesn't look like it has any side-effects (i.e., modifying the string) whereas reverse() is impure because it changes the state of the array.

1
  • It's a related concept, but also implies other properties (e.g. not accessing global state and always yielding the same output for the same input). Commented Mar 10, 2017 at 9:19
1

These would usually be separated into functions and methods (where methods are a subset of functions). A function is a section of code that can be called in isolation, whereas a method has a concept of a current 'context' on which it operates. The action of a method changes the state of its context.

In object oriented programming, the context is the instance that the function is operating on.

0

I don't know that there is an official answer, but here's two you might like.

Procedure

Only because it seemed like a good answer to this question, which looks a lot like your question BTW-- you should check it out.

In-place unary operation

Review this page: java.util.function. It provides a sort of made-up name for delegates (input/output signatures) of various prototypes, e.g. a delegate which takes an argument and returns nothing is called a consumer.

Now, as an astute student of OOP, you ought to be aware that an a method is just a function which takes a hidden parameter (this). Since it is supplied as a reference, it serves as both an input and an output parameter.

According to these Java guys (and they seem pretty smart), a delegate which accepts a single input and returns a value of the same type is called an unary operator.

Now in the case of array::Reverse(), an array is not immutable, and can potentially take up a lot of space, so it is more efficient and convenient to perform the operation in place. Therefore Reverse() is an in-place unary operator.

But to me, an "operator" is a special symbol (like the addition operator, also known as +) or a mathematical keyword like mod. Therefore I prefer to call it an operation, yielding in-place unary operation.

3
  • You're mixing up concepts. Reverse() is not an operator, a unary operator needn't return a value of the same type (e.g. !, delete, typeof), and operators are not delegates. But "in-place" is a fine term for a method that modifies its instance. [I didn't down-vote, but it looks like someone down-voted all the answers even though they're all useful.]
    – Jerry101
    Commented Mar 11, 2017 at 3:12
  • Not sure you are following. Any prototype can be represented by a delegate. "Operator" doesn't work for me (as I stated) so I say "Operation," and yes indeed Reverse() is a unary operation. But overall I agree this is all a little odd, yet I am using verbatim the terminology from the linked document, which seems to have been authored by some pretty smart folks. At least it is better than nothing.
    – John Wu
    Commented Mar 11, 2017 at 3:31
  • Oh, I see! Note that to retrofit lambdas into Java, they built on the idea of a functional interface (a Java interface with only 1 method) so we can pass around ordinary Java objects to apply as "functions." (Brian Goetz has a tech talk on adding lambdas. Multiple times he says "the obvious approach would've sucked.") When creating functional interfaces for stream processing objects, they kind of abused terms like "operator." That's confusing! They must've run out of good names. I don't think it's a good source of terms for OOP methods that do/don't modify the receiver object.
    – Jerry101
    Commented Mar 11, 2017 at 5:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.