The rule is no side effects. Mutating an object is a side effect. However it doesn't really say that you are mutating so here is a version of Payment where your code is pure:
public class Payment
{
private int value;
public Payment(int value) {
this.value = value;
}
public Payment setValue(int value) {
return new Payment(value);
}
public int getValue() {
return value;
}
public static int a(Payment payment) {
payment.setValue(payment.getValue() - 1); // dead code
return payment.getValue() * 10;
}
public static int b(Payment payment) {
return payment
.setValue(payment.getValue() - 1)
.getValue() * 10;
}
public static void main(String args[]) {
Payment p = new Payment(10);
System.out.println(String.valueOf(a(p)));
System.out.println(String.valueOf(b(p)));
}
}
Notice the definition of your a
isn't changed and it is 100% functional. If you pass it 10
it returns 100
, always 10 times the input. However the first line that returns a new Payment
with the value 9
is never used so it is dead code. The intent was perhaps that of my rewritten version, b
. b
is also functional.
Now other implementations of Payment
might make a
and b
impure.
Many people think OO and functional doesn't mix. One of the oldest and most commonly used class in Java, java.lang.String
, is both object oriented and a purely functional interface. No method mutates, only return a new object.