When taking the Wikipedia definition to the letter, a function that takes as argument a reference to a mutable data structure (such as a native Array) is not pure:
Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).
Equivalence
Although this clearly says "no variation with mutable reference arguments", we could maybe say this is open to interpretation and depends on the meaning of "same" and "variation". There are different definitions possible, and so we enter the area of opinion. Quoted from the paper your referred to:
There is not a single obviously right answer to these questions. Determinism is thus a parameterized property: given a definition of what it means for arguments to be equivalent, a method is deterministic if all calls with equivalent arguments return results that are indistinguishable from within the language
The functional purity proposed in the same paper, uses the following definition of equivalence:
Two sets of object references are considered equivalent if they result in identical object graphs
So with that definition, the following two arrays are considered equivalent:
let a = [1];
let b = [1];
But this concept can not really be applied to JavaScript without adding more restrictions. Nor to Java, which is the reason why the authors of the paper refer to a trimmed-down language, called Joe-E:
objects have identity: conceptually, they have an “address”, and we can compare whether two object references point to the same “address” using the ==
operator. This notion of object identity can expose nondeterminism.
Illustrated in JavaScript:
const compare = (array1, array2) => array1 === array2;
let arr = [1];
let a = compare(arr, arr);
let b = compare(arr, [1]);
console.log(a === b); // false
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…