[External] : Re: Changes to JEP 453
Robert Engels
rengels at ix.netcom.com
Wed May 31 12:07:19 UTC 2023
I’m going to add 2 cents to this.
After reviewing a lot of streams code that wraps checks exceptions into runtime exceptions - in order to work - it becomes clear the streams api is horrible and absolutely terrible for long-term maintenance. If you use streams with anything but pure functions you are creating lots of grief for the next dev.
This api is giving me similar pause. If we don’t have a clean way of dealing with checked exceptions we are creating the same mess all over again.
This feels like something that needs first class language support/syntax rather than a bolt on.
> On May 31, 2023, at 6:35 AM, Ron Pressler <ron.pressler at oracle.com> wrote:
>
>
>
>> On 26 May 2023, at 11:32, forax at univ-mlv.fr wrote:
>>
>> yes, no inference because the Java type system lacks unions.
>> But i see the explicit declaration of the common exception has an advantage more than a burden, you care once about the type of the exception and the STS implementation deals with the exceptions properly, the same way the type of the result is correctly propagated.
>>
>
> I am sympathetic to your suggestion because among all the designs we explored, we tried a design that propagates exceptions automatically. It was, in my opinion, more theoretically satisfying than STS, because it works like a parallel analogue of a for loop. Just as any exception inside the body of a for loop propagates outside the loop unless it is caught in the body of the loop, any exception in a fork — whether checked or unchecked — is automatically propagated unless caught in the body of the fork. This was quite elegant.
>
> But in the end we decided to go down a different path because the propagating “parallel for” one was, we felt, a tad too clever for our first structured concurrency construct. Instead, we designed STS to very much *not* propagate exceptions, and let the policy decide what to do with them. STS encourages examining the exceptions in the policy and then throwing a new wrapped exception. Yes, it makes refactoring sequential code into parallel code less automatically-composable, but it makes the multithreaded nature of the code more explicit — both in the code and in the exception stack traces — and we felt that is more appropriate as an introduction to structured concurrency.
>
> Now the question is, with the design we’ve chosen and that we primarily designed for wrapping fork exceptions rather than directly propagating them — for all its pros and cons — does it make sense to restrict the checked exceptions thrown by the forks? Given that this design requires the explicit handling of unchecked exceptions, which are not restricted by the extra type parameter anyway — something that is not the case for the return type — I think the answer is uncertain at best, so we figured might as well opt for a simpler API and type parameter fewer.
>
> You may say that your suggestion gives us the best of both worlds: those who wish to wrap exceptions can do so, and those who want to propagate them can do it more easily and type-safely (I see how it could still work nicely with ShutdownOnFailure but not as nicely with other policies). But one could just as easily claim that it gives us the worst of both worlds: It doesn’t have the architectural elegance of the “parallel for” design, and it makes STS a bit more complicated. I don’t think we have the empirical knowledge to make a determination at this point. Maybe we will in one more release, and maybe it would take longer and we could add other structured concurrency constructs in the future.
>
> There are so many possible structured concurrency constructs, some much cleverer than STS (we were overwhelmed by the variety of sensible choices), and I’d love to see libraries experimenting with them. As structured concurrency is better understood by Java programmers, we could consider adding cleverer SC constructs to the JDK.
>
> Finally, I know that the general question of checked exception composability is near and dear to your heart, but STS is no more afflicted by this issue than other JDK constructs, and I’d rather see a more general approach supported by the language itself.
>
>>
>> I believe that in that case, the future subclass of STS with a join() that takes a function with a stream is the way to handle centralized logging because only the result|exception of the tasks that have get outside of handleComplete() will be seen by the stream.
>
> This argument doesn’t fly because most logging of exceptions, like most code, is not and should not be aware it’s running inside STS. In any event, this kind of centralised logging is not something we want to encourage people to do with STS. However, your suggested third built-in policy has other merits, and we’ll definitely consider adding it.
>
> — Ron
More information about the loom-dev
mailing list