The motivation is that the question of whether list.forEach (or maybe better, iterable.forEach) is serial or parallel is to be left up to the implementation of the collection. Everything related to multi-threaded code since about Java 5 has been about hiding the details of concurrency and allowing programmers to think about code in a serial fashion, but still get the gains from multi threaded code.
It's not necessarily about parallelism either -- you could just as easily pass in a function as some sort of callback that gets called far in the future, for example,
> What does that even mean? Does the execution context need to be kept hanging around?
Once the block containing the declaration of 'error' has been exited, the only way anything could refer to 'error' would be if there were at least one additional lambda expression in the same block that was closed over the same binding of 'error'. Two such lambda expressions could thus communicate with each other through the shared binding.
It's not necessarily about parallelism either -- you could just as easily pass in a function as some sort of callback that gets called far in the future, for example,
String error = null; return createClientWithErrorHandler(e -> { error = e; });
What does that even mean? Does the execution context need to be kept hanging around?
Java already provides good atomic references if you need to have a sum variable or anything similar.