Meaning and Usage of Tasks

Eric Kolotyluk eric at kolotyluk.net
Thu Nov 18 20:18:57 UTC 2021


Reading some of the documentation I am getting confused about the meaning
of a 'Task' and wrote about this earlier in Threads vs Tasks...

Initially, these were just Runnable, and then could also be Callable (which
is better). Is it interesting to note in StructuredExecutor there are
different signatures for

.execute(Runnable)
.fork(Callable)

And I appreciate the distinction because calling .submit(Runnable |
Callable) can blur things, but can also see that .submit() may be more
attractive to some. Also, Callable can throw a Checked Exception, whereas
Runnable cannot. Can someone please explain the reason for this design
change?

I especially appreciate that both Runnable and Callable can be expressed
with Lambda expressions, especially coming from a background of Akka/Scala,
where Actors .spawn() other Actors, and can use Lambda expressions.
However, in Akka Typed we often use forms such as

object GreeterMain {

  final case class SayHello(name: String)

  def apply(): Behavior[SayHello] =
    Behaviors.setup { context =>
      val greeter = context.spawn(Greeter(), "greeter")

      Behaviors.receiveMessage { message =>
        val replyTo = context.spawn(GreeterBot(max = 3), message.name)
        greeter ! Greeter.Greet(message.name, replyTo)
        Behaviors.same
      }
    }}

where the Behaviors.setup { context => ... is a Lambda that takes a
'context'

Now I am not advocating adopting the Akka style, but it makes me wonder
what it would look like if we had capabilities like

structuredExecutor.spawn( () => {task implementation} )
structuredExecutor.spawn( context => {task implementation} )
structuredExecutor.spawn( (context, thingy) => {task implementation} )
. . .

and so on, where context is something not available in the session because
the structuredExecutor is available to the task implementation. I am just
thinking out loud here, where not all Tasks need the context, thingy, etc.,
but some may benefit from them. More importantly, is there some concept of
Task that goes beyond Callable, that cannot be satisfied by adding more
features to Callable?

I am pretty sure the Loom Architects have already walked down this path so
I would like to know if they could share their thoughts on this.

I am not hung up on a single .spawn() for multiple task types, but I like
the name because it brings a sense of 'family' to concurrent programming. ��

In my mind, a Task is *not *a Thread, it is something else that can be
executed on a Thread, but it should always be implementable by a Lambda.

Cheers, Eric


More information about the loom-dev mailing list