4 ms·
>All in all, why is the code not just: Because it's hard to review, too many things are happening on one line. What if you have to negate multiplication? You'
by agilob 5y ago
>All in all, why is the code not just:
Because it's hard to review, too many things are happening on one line.
What if you have to negate multiplication? You're messing that line even more, with streams, you're adding one line that's easy to read, easier to review, track changes.
- watwut 5y ago> What if you have to negate multiplication? Add sum *= -1; on the next line if you think the line is already too complex. Or just do return -sum;
- agilob 5y agoThe example is using BigDecimal class where arithmetic operators don't work, you need to call .negate() on the object, or multiply again BigDecimal("-1"). Negating inside a loop will give different result than multiplying at the end in return line. Nevertheless, you're adding ANOTHER operation to the line which is already complex and hard to read.
- watwut 5y agoThe exactly same thing can be said about stream version. There is no meaningful difference between the two when it comes to this change - either you do it in the middle of loop or add line for it. Except that the stream version is harder to debug and read, but more effective on potentially unlimited stream.
- agilob 5y agoYou add a new line with .map or .peek before .collect
- watwut 5y agoWhich is oh so much different then to add the new line into the imperative code? Adding new line into imperative code tend to be simple.
- agilob 5y agoFluent interfaces spread complexity of reading complex operations into multiple lines, you're squeezing everything into one line where tracking few characters change will be difficult to review, difficult to compare changes, bisect bugs (change in a complex line vs addition of a new simple line). Adding new line is simple change with no increased reading complexity. Modifying already complex line to add new operation will only increase complexity, change log of this line, making it all harder. That's all I'm saying, I'd rather read 11 simple lines, than 4 complex lines.
- watwut 5y agoI can add one new line into procedural code that does exact same thing. It wont increase reading complexity either. It wont even force me to think about what hidden map parameters. It will all be visible directly.
- setr 5y agoA new .map line has limited scope of access, and thus highly restricted possibilities. The same line in a for-loop can access anything, including things from other lines. The primary benefit of these kinds of functional chains is that each step is highly constrained in their capabilities, mainly by their function name and access scope, so you can better verify that it really does do what it says on the tin. A for loop’s content has to be ultimately read thoroughly, because anything goes. Including modifying lists unrelated to the list under question.
- watwut 5y agoThe price for that limited scope is that it is much harder to figure out what is actual parameter of lambda that goes into map function. If is also not even limited all that much. In lambda, everything from surrounding scope is visible too. My personal issue with these is that it is all harder to reason about, harder to read, harder to debug. And each time there is real issue, I have to unpack these into procedural, fix and then encrypt again. I dont see less bugs in code since we started using these. Bugs did not dropped.