Researching this topic I found the following warning:
CAVEAT.
In general, a function that receives mutable parameters is expected not to modify them, since changing them could lose valuable information.
In the event that the received parameters are modified due to a design or specification decision, this must be clearly documented within the postconditions.
Is there a norm or standard in this regard or is this warning an opinion of the author?
As a general rule, a function should not have any side effects and return a result based solely on the values of the input arguments.
In addition to losing information, it is also important to keep the variables and objects that are going to be shared immutable (eg: concurrent programming).
That is why, before modifying an argument, the recommendation is to make a copy and work on the copy.
Let's see some cases:
As a known case of a mutable argument it would be passing a list:
By sorting the list we have lost the original order. Similarly, if we alter any element we would lose the original list.
The recommendation would be to use a copy. In the case of lists, the function
sorted
already creates a copy for us:In the case of arguments that have default values, it is considered bad practice to use lists as default values. Let's see the reason:
If we try:
The default value itself mutates, which ends up being uncontrollable. The recommendation is to never use mutable values in defaults. The idea would be something like this:
Finally, it would be necessary to explain when it is admissible for an argument to change. In general, this would be in cases where a "change of state" occurs during the execution of the function. It is a way of signaling to other processes that there has been a change so that they can respond appropriately.
As a recommendation, implement the states as "properties" (
properties
) to have better control of when and how the state can be changed.An example:
Our instance of
Data
only allows its value to be changed through the methodappend
from which the state is controlledempty
. This way, when the function mutates the instance, it will change the stateempty
fromTrue
toFalse
.