<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Just some thoughts on Threads, Task, etc... please ignore if you
      think I am out to lunch...</p>
    <p>Originally, Project Loom started with the notion of Fibers, but
      then change the name to VirtualThreads. I liked "Fibers" but I
      agree that "VirtualTreads" makes more sense in some ways.</p>
    <p>When we talk about "Tasks" we usually think about concurrent
      things, where a Task is an abstract concept of concurrency and a
      Thread is an implementation.</p>
    <p>Task is what</p>
    <p>Thread is how</p>
    <p>If we changed the term "VirtualThread" to "Subthread" then there
      would be better symmetry with "Task" and "Subtask" but it's far
      too late to change the name "VirtualThread" and I am not sure if I
      like the term "VirtualTask" but I could live with it.</p>
    <p>In a way, we could create a symmetry between Task and Thread,
      where every Task has a Thread. Maybe this is a useless symmetry,
      but creating a Task does not mean you have to start the thread,
      just that it's the root of abstraction on concurrency, where
      thread is the root of implementation.</p>
    <p>Then comes the question of Scope...</p>
    <p>I proposed something like this a long time ago, but at the time
      people claimed this was unnecessary abstraction, and then later
      came Structured Concurrency... oh well...</p>
    <p>I have since seen discussions on StructuredTaskScope and now
      ScopedValue, but it's not clear to me that StructuredTaskScope
      implies ScopedValue? It doesn't but it can. Both
      StructuredTaskScope and ScopedValue are examples of dynamic scope.<br>
    </p>
    <p>Maybe instead of saying</p>
    <p><font face="monospace"> try (var scope = new
        StructuredTaskScope<Object>()) {<br>
        <br>
                Subtask<String> subtask1 = scope.fork(task1);<br>
                Subtask<Integer> subtask2 = scope.fork(task2);<br>
        <br>
                scope.join();<br>
        <br>
                ... process results/exceptions ...<br>
        <br>
            } // close</font></p>
    <p>we should be saying</p>
    <pre class="snippet"><code class="language-java"> try (var scope = Task.StructuredScope<Object>()) {

        Subtask<String> subtask1 = scope.<span class="bold">fork</span>(task1);
        Subtask<Integer> subtask2 = scope.<span class="bold">fork</span>(task2);

        scope.<span class="bold">join</span>();

        ... process results/exceptions ...

    } // <span class="bold">close</span></code></pre>
    <p></p>
    <p>where we have to figure out what we really mean by "Task" and
      "Subtask"</p>
    <p>Given that Subtask is a sub-interface of Supplier<T> ,
      maybe Task should also be a sub-interface of Supplier<C>
      where C is some Collection class. This might make concurrent
      collection based coding more elegant, where we state our intention
      to 'Supply' some collection via get().<br>
      <br>
      Where we have</p>
    <pre class="snippet"><code class="language-java">   private static final ScopedValue<String> USERNAME = ScopedValue.newInstance();

    ScopedValue.runWhere(USERNAME, "duke", () -> {
        try (var scope = new StructuredTaskScope<String>()) {

            scope.fork(() -> childTask1());
            scope.fork(() -> childTask2());
            scope.fork(() -> childTask3());

            ...
         }
    });</code></pre>
    <p></p>
    <p>we might have</p>
    <pre class="snippet"><code class="language-java">   private static final Scope.Value<String> USERNAME = Scope.Value();

    Scope.Value.runWhere(USERNAME, "duke", () -> {
        try (var scope = new Task.StructuredScope<String>()) {

            scope.fork(() -> childTask1());
            scope.fork(() -> childTask2());
            scope.fork(() -> childTask3());

            ...
         }
    });
</code>
</pre>
    <p>but I want to say something (not well thought out yet) like<code><br>
      </code></p>
    <code class="language-java"></code>
    <pre class="snippet"><code class="language-java">    List<String> results = Task.Builder(workers)
        .scope.value<String>("USERNAME", "duke")
        .scope.structured<String>( context-> {
            </code><code class="language-java"><code>List<Subtask<T>> subtasks
                = workers.stream().map(scope::fork).toList();
            context.join()
                .throwIfFailed();  // Propagate exception if any subtask fails
            // Here, all tasks have succeeded, so compose their results
            return subtasks.stream().map(Subtask::get).toList();
</code>        })
        .start();
</code>
<code class="language-java"></code></pre>
    <p></p>
    <p>Where the "try" is implicitly there... where it's boilerplate I
      don't need to see. I am learning to appreciate the Builder Pattern
      a little more, and wondering if Loom could make better use of it.<br>
    </p>
    <p>Anyway, just thinking out loud, and perhaps these discussions are
      better shared over beer? I know that the Scala community prefer
      Scotch, primarily Ardbeg, which is perhaps why Scala Architecture
      looks different than Java Architecture ;-)<br>
    </p>
    <p>Again</p>
    <blockquote>
      <p>There are only two hard things in Computer Science: cache
        invalidation and naming things.</p>
      <p class="quote-attribution">-- Phil Karlton</p>
      <p class="quote-attribution"><br>
      </p>
    </blockquote>
  </body>
</html>