[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[jdt-dev] A matter of style: loops vs. streams and - gasp - braces
|
Hi team,
(The following debate is as old as the invention of braces, but Java 8 gives a
new twist to it, so please bear with me for minute as I turn your world upside
down).
In a current gerrit I found the following comment:
> Also add missing braces on loops as necessary.
I doubt that any of those braces where "necessary", otherwise those would have
been bugs, no?
I'd like to actively promote a braceless style for simple loops and ifs for the
following reason:
Since Java 8 and the introduction of streams we have two main options for
writing many things involving iteration over a collection. As a trivial
first-level criterion to choose among the two, everybody uses "conciseness" of
the code.
Take this pattern:
for (X x : coll) {
if (isGood(x)) {
process(x);
}
}
vs.
coll.stream().filter(x -> isGood(x)).forEach(x -> process(x));
Everybody can "clearly see" that the latter variant is "better".
NO, it is not. We simply cheat by choosing a more condensed layout.
In terms of conciseness, this is the winner:
for (X x: coll) if (isGood(x)) process(x);
Do you see, how the initial example compared apples and oranges??
The stream() variant even has its own drawback: it will severely backfire should
you ever need to debug that code section.
So my proposal is: Let's for a compromise explicitly admit this style:
for (X x : coll)
if (isGood(x))
process(x);
IMHO this is the sweet spot to balance conciseness, readability and debuggability.
For slightly more involved cases I made a habit of using braces for the
outer-most structure, thus delineating a meaningful chunk of code, s.t. like
for (X parent : coll) {
if (isGood(parent))
for (Y child : parent.getChildren())
process(child);
}
Remember, that we provide quick assists for converting to block, should we need
to add more statements to some body.
If you don't like any of this, we should for fairness also forbid braceless
lambdas and enforce line breaks around the lambda body:
coll.stream().filter(x -> {
return isGood(x);
}).forEach(x -> {
process(x);
});
This style is suitable for comparison with the old, imperative style (but ugly,
right?)
No, I'm not against lambdas (just a bit wary about debuggability), but visual
comparison between options should be fair :)
Put differently: a loop structure that can be written without braces has the
same mental clarity as a well structure stream-pipeline. Let's please not
penalize such style by unnecessary verbosity.
best,
Stephan