# Elm concurrent tasks

**URL:** https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450
**Category:** Request Feedback
**Created:** [November 12, 2023, 4:42pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450 "2023-11-12T16:42:13Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![elmdev](https://avatars.discourse-cdn.com/v4/letter/e/919ad9/32.png) [@elmdev](https://discourse.elm-lang.org/u/elmdev)
#### Post date: [November 12, 2023, 4:42pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/1 "2023-11-12T16:42:13Z")

</div>

The latest elm radio - [elm-concurrent-task with Andrew MacMurray](https://elm-radio.com/episode/elm-concurrent-task) - was a good listen and an interesting technical solution to the surprising fact that `Task.mapX` is as sequential as … `Task.sequence` and `Task.andThen`. The starting discussion noted that parallel tasks with individual callbacks is generally the ‘javascript way’.

But the elephant in the podcast was why there is no momentum to addressing this un-intuitive situation, or at least the adding of an option for parallelization.

This is when Elm becomes frustrating. Things aren’t always right, but there’s no questioning of them, and little prospect of improvement.

---

<div class="post-metadata">

### Author: ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)
#### Post date: [November 12, 2023, 8:04pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/2 "2023-11-12T20:04:15Z")

</div>

Why would you expect any parallelism out of `Task.map`? There isn’t more than one thing that could be parallelized.

---

<div class="post-metadata">

### Author: ![gampleman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gampleman/32/43_2.png) [@gampleman](https://discourse.elm-lang.org/u/gampleman)
#### Post date: [November 12, 2023, 10:52pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/3 "2023-11-12T22:52:06Z")

</div>

I think they meant `map2` and friends.

---

<div class="post-metadata">

### Author: ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)
#### Post date: [November 13, 2023, 7:19am UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/4 "2023-11-13T07:19:36Z")

</div>

Ah, that makes sense, and it’s also surprising to me that it wouldn’t be parallel!

It seems to me that elm-concurrent-task itself is “momentum to addressing this un-intuitive situation, or at least the adding of an option for parallelization”, so I’m not sure I understand what the OP is getting at.

---

<div class="post-metadata">

### Author: ![uweg](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/uweg/32/2541_2.png) [@uweg](https://discourse.elm-lang.org/u/uweg)
#### Post date: [November 13, 2023, 7:53am UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/5 "2023-11-13T07:53:54Z")

</div>

It is also clearly stated in the [documentation](https://package.elm-lang.org/packages/elm/core/latest/Task#map2):

> **Note:** Say we were doing HTTP requests instead. `map2` does each task in order, so it would try the first request and only continue after it succeeds. If it fails, the whole thing fails!

---

<div class="post-metadata">

### Author: ![elmdev](https://avatars.discourse-cdn.com/v4/letter/e/919ad9/32.png) [@elmdev](https://discourse.elm-lang.org/u/elmdev)
#### Post date: [November 17, 2023, 10:23am UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/6 "2023-11-17T10:23:10Z")

</div>

yes it was a typo as @gampleman pointed out.  
@uweg - it might be documented, but it is still un-expected absent of reading the docs, and fundamentally slows all Elm apps down that could leverage parallel cmds (Elm will lose some speed comparisons for this alone)

---

<div class="post-metadata">

### Author: ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)
#### Post date: [November 17, 2023, 12:33pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/7 "2023-11-17T12:33:25Z")

</div>

I wonder… are we talking about _parallel_ or _asynchronous_ here?

If I have parallel computations running, they are going to be running at the same time on my system. So \>1 CPU will be active. This is generally what I understand by the term _parallel_, since it is frequently used in conjunction with talking about parallel processing.

If I have asynchronous processes, they could be running in sequence, or in parallel, so 1 CPU core or \>1 CPU core. Synchronous processes could also be running in parallel with thread operators such as `spawn` and `join`.

I suppose we had better think about the term _concurrent_ also. Its sort-of the same thing as parallel, except maybe not. The user could be moving their mouse concurrently to waiting for some HTTP request to complete. The mouse and the HTTP request are not processing jobs that happen on my machine, their are concurrent tasks happening in the real world, outside of my machine. So its a bit different than what I normally associate with the word _parallel_.

So I think we are talking about _concurrent_ _asynchronous_ event handling here.

Javascript in the browser is single threaded, so there is no parallel execution. Its programming model is asynchronous though. There are web workers that can run parallel CPU jobs in the browser, it is also worth noting. Web workers programming model is awkward and certainly not ideal for concurrent functional programming where you might want to be able to pass continuations between threads - it does not allow this.

To give an example, suppose I want to GET 2 HTTP endpoints. If I create 2 tasks, one for each, and run then with Task.map2. The [docs](https://package.elm-lang.org/packages/elm/core/latest/Task#map2) say:

“ **Note:** Say we were doing HTTP requests instead. `map2` does each task in order, so it would try the first request and only continue after it succeeds. If it fails, the whole thing fails!”

```auto
map2 : (a -> b -> result) -> Task x a -> Task x b -> Task x result
map2 func taskA taskB =
  taskA
    |> andThen (\a -> taskB
    |> andThen (\b -> succeed (func a b)))

```

It certainly seems possible that `map2` could execute the 2 asynchronous tasks concurrently, then `join` and combine their results once both have completed. It also seems correct that `andThen` always processes sequentially, not starting the second task until the output of the first one completes. Presumably `map2` could be re-written as a special case not making use of `andThen`.

Would be interesting to see in code how this could be done? A hypothetical kernel function for example, can anyone write it to show how?

Does this run 2 Tasks concurrently? [Process - core 1.0.5](https://package.elm-lang.org/packages/elm/core/latest/Process#spawn) . The description in the docs certainly seems to be suggesting that it does:

" Run a task in its own light-weight process. In the following example, `task1` and `task2` will be interleaved. If `task1` makes a long HTTP request or is just taking a long time, we can hop over to `task2` and do some work there.

```auto
spawn task1
  |> Task.andThen (\_ -> spawn task2)

```

**Note:** This creates a relatively restricted kind of `Process` because it cannot receive any messages. More flexibility for user-defined processes will come in a later release!"

---

<div class="post-metadata">

### Author: ![wolfadex](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/wolfadex/32/2461_2.png) [@wolfadex](https://discourse.elm-lang.org/u/wolfadex)
#### Post date: [November 17, 2023, 1:23pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/8 "2023-11-17T13:23:09Z")

</div>

There was a fair amount of discussion around parallel vs concurrent in the naming of [elm-concurrent-task with Andrew MacMurray](https://elm-radio.com/episode/elm-concurrent-task), along with parts of elm-pages. Technically JS runs concurrently, though maybe with workers you could run in parallel?

* * *

As for Elm’s `Task.mapN`, it would be nice to have a concurrent/parallel implementation as well as the sequential one. Sequential is nice when you only want the subsequent calls to happen if the priors succeed. Like a `map7` where the first task fails, I wouldn’t then want 6 expensive tasks to continue processing.

> [@elmdev](#):
>
> Things aren’t always right

I’m not sure what’s wrong here, the docs are explicit and I’d argue there is no intuitive way to interpret whether a function is sequential or parallel. Either the function name is explicit, or you have to read the docs.

---

<div class="post-metadata">

### Author: ![elmdev](https://avatars.discourse-cdn.com/v4/letter/e/919ad9/32.png) [@elmdev](https://discourse.elm-lang.org/u/elmdev)
#### Post date: [November 17, 2023, 7:25pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/9 "2023-11-17T19:25:33Z")

</div>

Just to be clear, when I do Task.mapX and see in the chrome dev console that the second task does not event start until the first one finishes, I could move it all to commands and then write boilerplate to wait until all X task have completed, or I could implement elm-concurrent-task, or I could wonder why the default Elm behaviour is not completely ‘delightful’.

(Yes, if there’s a strong chance of failure, then perhaps doing the riskiest first is reasonable, but I’m thinking about a set of calls to my server to initialise my app. Yes then I could even ask the backend team to provide a route that groups them, but that’s feels rather brittle)

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [November 27, 2023, 7:26pm UTC](https://discourse.elm-lang.org/t/elm-concurrent-tasks/9450/10 "2023-11-27T19:26:11Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
