6

Is a function that changes the values of an input argument still a pure function?

My example (Kotlin):

data class Klicker( var id: Long = 0, var value: Int = 0 ) fun Klicker.increment() = this.value++ fun Klicker.decrement() = this.value-- fun Klicker.reset() { this.value = 0 } 

Wikipedia says a pure function has these two requirements:

  1. The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change while program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices.
  2. Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.

From my understanding, all functions from my example comply with the first requirement.

My uncertainty starts with the second requirement. With the change of the input argument, I mutate an object (rule violation), but this object is not outside of the function scope, so maybe no rule violation?

Also, does a pure function always need to return a completely new value?

I presume, this function is considert 100% pure:

fun pureIncrement(klicker: Klicker): Klicker { return klicker.copy(value = klicker.value++) } 

Be gentle, this is my first Stackoverflow question.

2
  • In fact, even pureIncrement mutates klicker.value with ++, so it's not pure. Commented Mar 2, 2018 at 12:33
  • An easier check for purity: "Would the behavior of the program change if I replace the function call with its results here?" Commented Mar 2, 2018 at 12:48

1 Answer 1

4

The increment and decrement functions fulfill neither of the requirements for a pure function. Their return value depends on the state of the Klicker class, which may change while program execution proceeds, so the first requirement is not fulfilled. The evaluation of the result mutates the mutable Klicker instance, so the second requirement is also not fulfilled. It doesn't matter in which scope the mutable data is; a pure function must not mutate any data at all.

The reset function violates only the second requirement.

The pureIncrement function can be made pure if you change it to:

fun pureIncrement(klicker: Klicker): Klicker { return klicker.copy(value = klicker.value + 1) } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.