<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<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">
Hi Subrahmanyam,</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">
There are a multitude of possible Structured Concurrency APIs, all with different trade-offs in discoverability, ease-of-use, difficulty-of-misuse, performance, composability, maintainability, reviewability, and more. (Alan and I have prototyped dozens of different
ones.)</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 an API with the shape you outline above would suit your use-case(s), it does look tractable for you to create that on top of Structured Concurrency APIs from the JEP.</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: 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> loom-dev <loom-dev-retn@openjdk.org> on behalf of Subrahmanyam V <vemana.github@gmail.com><br>
<b>Sent:</b> Thursday, 21 August 2025 13:07<br>
<b>To:</b> loom-dev@openjdk.org <loom-dev@openjdk.org><br>
<b>Subject:</b> Style difference between StructuredTaskScope and ScopedValue APIs</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div dir="ltr">Hello all, I am new here but just wanted to ask a question & share a thought on StructuredTaskScope API.
<div><br>
</div>
<div>What's the reason for the asymmetry between ScopedValue and StructuredTaskScope APIs? Symmetry would suggest something like `StructuredTaskPolicy.create(Supplier<Joiner>).call(Function<StructuredTaskScope, T>)`. </div>
<div><br>
</div>
<div>Note </div>
<div>(1) StructuredTask_Policy_. The _call_ method on a Policy instance creates a StructuredTaskScope, passes it to the Consumer/Function and closes it before returning. Scoped Value propagation should behave like in the current API.</div>
<div>(2) Supplier<Joiner> in constructor because Joiner is stateful.</div>
<div><br>
</div>
<div>On the surface, there are a few advantages to the symmetric API</div>
<div>1. [Immutable, well-defined Policies] StructuredTaskPolicy instances can be immutable and shared across the application and its many threads. I can imagine applications that use just 2 different policies {all-succeed, any-succeed} across tens or hundreds
of call sites </div>
<div>2. [Expressions] This API produces expressions instead of imperative constructs and thus composes better. For example, I can do: `return awaitUniterruptibly(() -> ALL_SUCCEED_POLICY.call(scope -> {...}));`.</div>
<div>3. [Managed Scope lifecycle] Let the API manage scope.close() to free resources instead of relying on the user. Hide lifecycle methods like open() and close() and expose only fork() and join() on StructuredTaskScope - the only ones that the user really
cares about.</div>
<div>4. [Brevity that leads to Clarity] Nesting is feasible given brevity and expressions (#2). For example, a single readable expression can express that two subtasks should each succeed where the first task is itself a StructuredTask made up of three subtasks
any of which succeeds, </div>
<div>5. [Easier evolution] If StructuredTaskScope.Config API evolves (this seems an active area of change), only Policy classes need to be evaluated by users for any potential migration instead of every call-site. A handful of immutable Policy classes is easier to
manage than 10s or 100s of call-sites.</div>
<div><br>
</div>
<div>But, on reflection, an application can get all of the above benefits if it sticks exclusively to the _race()_ or _runConcurrently()_ constructs from the JEP. That is, instead of _Policy Classes_, it uses _Policy Methods_ like race(). Which begs the question
- should the structured concurrency API also expose Policy Methods as a first class API, one Policy Method per Joiner?</div>
<div><br>
</div>
<div>Subrahmanyam</div>
<div><br>
</div>
<div><br>
</div>
</div>
</div>
</div>
</body>
</html>