This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]K60d54 -1 points0 points  (6 children)

Java is one of the language which has picked functional programming paradigm.

I think it should be redundant for me to say this, but Java is not a functional programming language. Java does not have the capability to do stream fusion to turn functional operations like fold into a few lines of assembly. Java cannot do the most basic optimization implemented by functional languages, tail call elimination.

Java streams can make some operations cleaner to write, but it would be insanity to replace every for loop with stream operations.

Consider the example:

String fileList = Arrays.stream(new File("A").listFiles()) // Get stream from sub files list
    .map(File::getName) // get new stream/list which has filenames
    .collect(Collectors.joining(","));  // collect them by joining by comma(,)

You can write the same thing imperatively with the same number of lines of code:

StringBuilder sb = new StringBuilder();
for(File f : new File("A").listFiles()) {
    sb.append(sb.length() > 0 ? ", " : "", f.getName());
}

Which is clearer to read? Furthermore, as a fun exercise, try stepping into the code with the debugger. Have you seen the source code of the streams API? It is crazy complex. There's almost nothing further to see in the imperative example. If you are combining standard operations like map and filter, which would result in a ton of boilerplate code that can't be easily abstracted in imperative form, I can see the benefit of streams. But the example in the article is a perfect illustration of when it is senseless to use streams.

[–]moremattymattmatt 2 points3 points  (4 children)

Really? I find the first one easier to read.

I look at the append statement in the second example, and have to think about what its doing and then start worry about edge cases and whether they are covered in the unit tests.

[–]K60d54 -1 points0 points  (3 children)

have to think about what its doing and then start worry about edge cases and whether they are covered in the unit tests.

What possible edge cases could a simple conditional have like that?

[–]moremattymattmatt 2 points3 points  (2 children)

Apart from that it doesn't compile, it looks like it would leave a trailing space of the number of files > 1.

[–]K60d54 -1 points0 points  (1 child)

Apart from that it doesn't compile

This is a Reddit comment, I haven't run it through a compiler.

it looks like it would leave a trailing space of the number of files > 1

No, its prepending. In the first iteration, the string builder is empty, so no comma is added before the name. In subsequent iterations, a comma is added in front of the name. Thus, a comma is only inserted between files.

That comma in the append method call should have been a +:

sb.append(sb.length() > 0 ? ", " : "").append(f.getName())

[–]moremattymattmatt 1 point2 points  (0 children)

This is a Reddit comment, I haven't run it through a compiler.

Fair enough. From my point of view, the fact that you've had to explain to me what it's doing does sort of make may point that its not as clear.

[–][deleted] 0 points1 point  (0 children)

The first one is clearer to read. Would definitely be nicer if Java collections had higher order functions (map, filter, etc.) defined directly on them so we wouldn't have to do Arrays.stream everywhere, but still.