<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Trying to come up with an example on the spot is always challenging, so if the following doesn't make sense in your case(s) let me know (and, fair warning, I just typed it into the email client, so this is unlikely to compile as-is).<br>
<br>
Now, imagine that you want to create the following logical structure of tasks (note that these are all concurrent):
<b><i>(A and B) or C</i></b></div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
You could go down the path of creating a bespoke Joiner that handles this case specifically, and then when you have
<b><i>(A and B and C) or D or E </i></b>you're likely to have to create yet another such custom thing (repeat for permutations thereof).</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
If you were to instead imagine you have the following two different joiners:</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
MyJoiners.<T>and() // takes tasks which produce a result of type T and joins them into a List<T> with all the results if all tasks are successful, and fails if any of them fail (see: Joiners.allSuccessfulOrThrow())</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
MyJoiners.<T>or() // takes tasks which produce a result of type T and returns the first result to complete successfully, and fails if all fail (see: Joiners.anySuccessfulResultOrThrow())</div>
<div class="elementToProof" id="Signature">
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
That would be equivalent to:</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
try (var orScope = StructuredTaskScope.open(MyJoiners.<List<String>>or())) {</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
orScope.fork(() -> {</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
try (var andScope = StructuredTaskScope.open(MyJoiners.<String>and())) {</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
andScope.fork(() -> "A");</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
andScope.fork(() -> "B");</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
return andScope.join();</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
}</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
});</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
orScope.fork(() -> List.of("C"));</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
return orScope.join(); // either ["A", "B"] or ["C"]</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
}</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
So while this is merely a (possibly contrived) example, I hope that it illustrates the notion of composition of scopes rather than the composition of Joiners.</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Cheers,<br>
√</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<b><br>
</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
<b>Viktor Klang</b></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> David Alayachew <davidalayachew@gmail.com><br>
<b>Sent:</b> Sunday, 17 August 2025 22:50<br>
<b>To:</b> Viktor Klang <viktor.klang@oracle.com><br>
<b>Cc:</b> loom-dev <loom-dev@openjdk.org><br>
<b>Subject:</b> Re: [External] : Re: My experience with Structured Concurrency</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div class="x_gmail_default" style="font-family:monospace">Hey, I've been trying out your idea, but I can't find a single place where doing it would apply.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">I understand the idea of nesting scopes well enough. For example, I could put a innerScope inside of a outerscope.fork() call. Alternatively, I could have another scope after the outerScope.join() call.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">But doing it the first way would mean that I am creating an entire scope for each outerScope subtask. Is that what you are proposing? That makes sense if there are multiple tasks worth of processing
that I want. For example, if the outerscope subtask would return a list of things, each of which, I could do further processing on. But that doesn't make sense if each outerScope subtask has only one "thing" that needs further downstream processing. The entire
point of a scope is to do multi-threading. Having one task defeats the purpose of that.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">And doing it the second way means I would have to wait for all of my tasks to complete from the outerScope before the innerScope could do anything.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">In both cases, I wouldn't really be able to gain anything for my composed joiners.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">And to be clear, most of my Joiner compositions were simply nesting and adding to an existing implementation. For example, I had a joiner that closed the scope after 3 counts of tasks failing with SomeException.
Well, I then used composition to make it cancel AND return the tasks up to and including the 3 failed. In that case, I don't see how I would gain anything by adding another scope.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace">Could you help me see what you had in mind? Maybe I am just lacking creativity.</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
<div class="x_gmail_default" style="font-family:monospace"><br>
</div>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Fri, Aug 15, 2025 at 8:04 PM David Alayachew <<a href="mailto:davidalayachew@gmail.com" target="_blank">davidalayachew@gmail.com</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="auto">
<div>Oh, I'm already doing that. Lol, I love STS BECAUSE nesting scopes is so easy to do.
<div dir="auto"><br>
</div>
<div dir="auto">But that's an interesting idea. I kind of see what you mean -- maybe I am stuffing too much logic into a single Joiner. I can't tell yet, so I guess I'll just have to try it out and get back to you.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Thanks for the tip.</div>
<br>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Fri, Aug 15, 2025, 5:09 PM Viktor Klang <<a href="mailto:viktor.klang@oracle.com" target="_blank">viktor.klang@oracle.com</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hi David,</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Thanks for the added detail, that really helps my understanding of your situation.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Did you try/consider/evaluate nested scopes (each with different Joiner strategies) over composing Joiners themselves?</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
And if you did, what were your findings when comparing those two different approaches?</div>
<div id="x_m_3931938170959872945m_2298583310143625616m_-2746072355101738475m_3630950667619938020m_-8531484976151811332Signature">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Cheers,<br>
√</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<b><br>
</b></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<b>Viktor Klang</b></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="x_m_3931938170959872945m_2298583310143625616m_-2746072355101738475m_3630950667619938020m_-8531484976151811332appendonsend">
</div>
<hr style="display:inline-block; width:98%">
<div id="x_m_3931938170959872945m_2298583310143625616m_-2746072355101738475m_3630950667619938020m_-8531484976151811332divRplyFwdMsg" dir="ltr">
<font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> David Alayachew <<a href="mailto:davidalayachew@gmail.com" rel="noreferrer" target="_blank">davidalayachew@gmail.com</a>><br>
<b>Sent:</b> Friday, 15 August 2025 20:53<br>
<b>To:</b> Viktor Klang <<a href="mailto:viktor.klang@oracle.com" rel="noreferrer" target="_blank">viktor.klang@oracle.com</a>><br>
<b>Cc:</b> loom-dev <<a href="mailto:loom-dev@openjdk.org" rel="noreferrer" target="_blank">loom-dev@openjdk.org</a>><br>
<b>Subject:</b> [External] : Re: My experience with Structured Concurrency</font>
<div> </div>
</div>
<div>
<div dir="auto">One other detail I'd like to highlight.
<div dir="auto"><br>
</div>
<div dir="auto">Much like Collectors and Gatherers, there are a handful of super useful ones that you use everywhere, and then the rest are ad-hoc, inline ones where you sort of just make your own to handle a custom scenario. If you use streams often, you will
run into those frequently, and that's why those factory methods are fantastic.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Well, I have kind of found myself in the same position for Joiners. Joiners aren't as complex as Collectors and Gatherers, so there has certainly been less need for it. But I am also only a few weeks into using Joiners (though, I used STS for
over a year). If I feel this strain now, then I feel like this experience is definitely worth sharing.</div>
</div>
<br>
<div>
<div dir="ltr">On Fri, Aug 15, 2025, 2:44 PM David Alayachew <<a href="mailto:davidalayachew@gmail.com" rel="noreferrer" target="_blank">davidalayachew@gmail.com</a>> wrote:<br>
</div>
<blockquote style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="auto">Sure.
<div dir="auto"><br>
</div>
<div dir="auto">Long story short, the biggest reason why STS is so useful for me is because it allows me to fire off a bunch of requests, and handle their failures and outcomes centrally. That is the single most useful feature of this library for me. It's also
why Future.status was not so useful for me -- it calls get under the hood, and therefore might fail! Handling that was too much scaffolding.</div>
<div dir="auto"><br>
</div>
<div dir="auto">So, when someone recently challenged me to use Joiners (rather than the old STS preview versions I was used to), I started creating Joiners to handle all sorts of failure and outcomes. At first, a lot of them could be handled by the Joiner.awaitUntil(),
where I would just check and see if the task failed, then handle the error. But as I got further and further along, I started needing to add state to my Joiners in order to get the failure handling that I wanted. For example, if a certain number of timeouts
occur, cancel the scope. Well, that necessitates an AtomicNumber.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Then, as the error-handling got more and more complex, I started finding myself making a whole bunch of copy paste, minor variations of similar Joiners. Which isn't bad or wrong, but started to feel some strain. Now, I need to jump through an
inheritance chain just to see what my Joiner is really doing. It wasn't so bad, but I did start to feel a little uneasy. Bad memories.</div>
<div dir="auto"><br>
</div>
<div dir="auto">So, the solution to a problem like this is to create a Joiner factory. Which is essentially what I started to write before I started remembering how Collectors and Gatherers worked. At that point, I kind of realized that this is worth suggesting,
which prompted me to write my original email.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Like I said, not a big deal if you don't give it to me -- I can just make my own.</div>
<div dir="auto"><br>
</div>
<div dir="auto">But yes, that is the surrounding context behind that quote. Let me know if you need more details.</div>
<br>
<br>
<div dir="auto">
<div dir="ltr">On Fri, Aug 15, 2025, 9:25 AM Viktor Klang <<a href="mailto:viktor.klang@oracle.com" rel="noreferrer noreferrer" target="_blank">viktor.klang@oracle.com</a>> wrote:<br>
</div>
<blockquote style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hi David,</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
First of all—thank you for your feedback!</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
I'm curious to learn more about why you ended up in the situation you describe below, specifically about what use-cases led you into wishing for an augmentation to Joiner to facilitate composition.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Are you able to share more details?</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-size:12pt"><span style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; color:rgb(0,0,0)">></span><span style="font-family:monospace; color:rgb(0,0,0)">Which, funnily enough, led to a slightly different
problem -- I found myself wanting an easier way to create Joiners. Since I was leaning on Joiners so much more heavily than I was for STS, I ended up creating many Joiners that do almost the same thing, with just minor variations. And inheritance wasn't always
the right answer, as I can't inherit from multiple classes. Plus, most of my joiners were stateful, but I only wanted the non-stateful parts of it. I could do composition, but it sort of felt weird to delegate to multiple other Joiners.</span></div>
<div id="x_m_3931938170959872945m_2298583310143625616m_-2746072355101738475m_3630950667619938020m_-8531484976151811332x_m_7197557199792604428m_3210627119907430337Signature">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Cheers,<br>
√</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<b><br>
</b></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<b>Viktor Klang</b></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="x_m_3931938170959872945m_2298583310143625616m_-2746072355101738475m_3630950667619938020m_-8531484976151811332x_m_7197557199792604428m_3210627119907430337appendonsend">
</div>
<hr style="display:inline-block; width:98%">
<div id="x_m_3931938170959872945m_2298583310143625616m_-2746072355101738475m_3630950667619938020m_-8531484976151811332x_m_7197557199792604428m_3210627119907430337divRplyFwdMsg" dir="ltr">
<font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> loom-dev <<a href="mailto:loom-dev-retn@openjdk.org" rel="noreferrer noreferrer noreferrer" target="_blank">loom-dev-retn@openjdk.org</a>> on behalf of David Alayachew <<a href="mailto:davidalayachew@gmail.com" rel="noreferrer noreferrer noreferrer" target="_blank">davidalayachew@gmail.com</a>><br>
<b>Sent:</b> Friday, 15 August 2025 11:52<br>
<b>To:</b> loom-dev <<a href="mailto:loom-dev@openjdk.org" rel="noreferrer noreferrer noreferrer" target="_blank">loom-dev@openjdk.org</a>><br>
<b>Subject:</b> My experience with Structured Concurrency</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div style="font-family:monospace">Hello <a id="x_m_3931938170959872945m_2298583310143625616m_-2746072355101738475m_3630950667619938020m_-8531484976151811332x_m_7197557199792604428m_3210627119907430337x_plusReplyChip-0" href="mailto:loom-dev@openjdk.org" rel="noreferrer noreferrer noreferrer" target="_blank">@loom-dev</a>,</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">I just wanted to share my experience with Structured Concurrency. I had actually been using it for a while now, but only recently got experience with the new Joiner. After trying it out, my previously stated opinion has changed.</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">Overall, Structured Concurrency has been a pleasure. I'll avoid repeating ALL my old thoughts and just highlight the KEY details.</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">* Structured Concurrency is excellent for complex error-handling. Receiving exceptions via the subtask makes all the error-handling less painful.</div>
<div style="font-family:monospace">* Structured Concurrency makes nesting scopes a breeze, a task I historically found very painful to do.</div>
<div style="font-family:monospace">* Inheritance allows me to take an existing Scope (now Joiner), and modify only what I need to in order to modify it for my use case. Great for reusing old strategies in new ways.</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">Now for the new stuff -- having Joiner be the point of extension definitely proved to be the right move imo. I didn't mention this in my original message, but while it was easy to get a scope set up using inheritance, it wasn't
always clear what invariants needed to be maintained. For example, the ensureOwnerAndJoined method. Was that something we needed to call when inheriting? On which methods? Just join()?</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">The Joiner solution is comparatively simpler, which actually meant that I ended up creating way more Joiners, rather than only several STS'. Joiners invariants are obvious, and there is no ambiguity on what is expected from
the implementor.</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">Which, funnily enough, led to a slightly different problem -- I found myself wanting an easier way to create Joiners. Since I was leaning on Joiners so much more heavily than I was for STS, I ended up creating many Joiners
that do almost the same thing, with just minor variations. And inheritance wasn't always the right answer, as I can't inherit from multiple classes. Plus, most of my joiners were stateful, but I only wanted the non-stateful parts of it. I could do composition,
but it sort of felt weird to delegate to multiple other Joiners.</div>
<div><br>
</div>
<div>
<div style="font-family:monospace">Part of me kept wondering how well a factory method, similar to the ones for Collectors and Gatherers, might fare for Joiners.</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">Regardless, even if we don't get that factory method, this library has been a pleasure, and I can't wait to properly implement this once it goes live.</div>
<div style="font-family:monospace"><br>
</div>
<div style="font-family:monospace">Thank you for your time and consideration.</div>
<div style="font-family:monospace">David Alayachew</div>
<br>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</body>
</html>