Mutation is changing an object and is one common side effect in programming languages.
A method that has a functional contract will always return the same value to the same arguments and have no other side effects (like storing file, printing, reading). Thus even if you mutate temporary values inside your function it's still pure from the outside. By putting your first example in a function demonstrates it:
public static int squareSum(const List<Integer> values)
{
int total = 0;
for(int e : values) {
total += e * 2; // mutates a local variable
}
return total;
}
A purely functional method doesn't even update local variables. If you put the second version in a function it would be pure:
public static int squareSum(const List<Integer> values)
{
return values.stream()
.map(e-> e*2)
.reduce(0, (c, e)-> c + e);
}
For a person that knows other languages that has long been preferring a functional style map
and reduce
with lambda
is very natural. Both versions are easy to read and easy to test, which is the most important part.
Java has functional classes. java.lang.String
is one of them.
values.stream().mapToInt(e -> e * 2).sum()
, which might be easier to follow. – Lobomap
andreduce
(fold
) is home ground. – Lordanc
instead oftotal
. The functional version should've been:values.stream().reduce(0, (total, e)-> total + e*2))
– Expressmantotal
, each with their own specialized complex logic, and see if it's still easy to understand. Thentotal
is no longer isolated, and you need run through all the changes in your mind to understand what the current state is/should be. – Expressman