I am confused about the notion of immutability. Consider the following structure of a simplistic calculator:
Here are the interfaces:
interface IOperationalInterface {
int Sum(int a, int b);
}
interface IAuditInterface {
int SumInvocations();
}
IOperationalInterface.Sum
should compute the sum of two integers and IAuditInterface.SumInvocations
should return the total number of received Sum
calls.
Here is a trivial implementation:
class CalculatorImpl : IOperationalInterface, IAuditInterface {
private int invocations = 0;
public int Sum(int a, int b) {
invocations++;
return a + b;
}
public int SumInvocations() {
return invocations;
}
}
Is CalculatorImpl
immutable? Obviously not, because its state changes with each invocation of the Sum
method. Is the Sum
operation pure? According to Wikipedia it is not, since it changes the state of a mutable object, and that side-effect is observable through the IAuditInterface
. Obviously the SumInvocations
operation is also not pure, since it may return different results.
In summary, CalculatorImpl
is mutable and all of its methods are impure.
However, from the viewpoint of CalculatorClient
, who talks to it only through the IOperationalInterface
, it appears to be immutable and the Sum
operation appears to be pure in the sense that it could not observe any side effects through that interface.
On the other hand, from the perspective of AuditClient
, it is completely different: it is obvious that the object implementing the AuditInterface
is mutable and its SumInvocations
operation is impure, and this follows directly from the specification of the IAuditInterface
.
So, it is possible to partition an interface/specification of a mutable class such that some parts of it will appear mutable and some not. In this case, considering only the Sum
operation and leaving out the requirement that the invocations should be counted, we get something that does not have any side-effects.
Now, on implementing the CalculatorClient
one can take into account the fact that the object behind the interface appears to be immutable. At least one could not tell the difference.
So my question is: does it make sense to talk about "immutability" of interfaces or is it a bad idea? How else can I communicate the fact that there will be no observable side-effects through that interface? And if it's bad, what could go wrong?
UPDATE
Thanks for your answers/comments! I see now that there is no way to say that the IOperationalInterface
is pure; the conditions of purity are much too strong to apply in this case. However the question remains whether there is a weaker notion (maybe "immutability"?) which is applicable.
a
andb
, any two invocations ofSum(a, b)
must return the same value"), that's valid. But "this method must not have any observable side effects" is invalid, IMO.