Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Traverse asyncs in parallel? #36

gusty started this conversation in Ideas
Discussion options

Should sequenceA [|x;y;z|] (for x, y and z asyncs) be semantically equivalent to Async.Parallel [|x;y;z|] ?

The operations are equivalent and currently will yield the same results, but sequenceA (or traverse id) will execute each async in sequence. Well that's probably what the name means ;)

The same way it is possible to implement a specific instance for zip where it zips two asyncs in parallel, but the question is: is it the right thing to do?

Any thoughts?

You must be logged in to vote

Replies: 6 comments

Comment options

gusty
Jan 20, 2018
Maintainer Author

I'll close this issue, since at this point I'm sure it's not the right thing to do.
Implicit parallelism is not a good idea, and I had some real world scenarios were it would have bitten.

The only question that remains open is how to explicitly generalize for parallel operations. ParallelArray was an attempt, but it doesn't include traverses and as it is an array, it only works for computations of the same type. Maybe we should add parallel tuples?

For the moment I would leave things as they are, unless someone have a better idea. Feel free to re-open.

You must be logged in to vote
0 replies
Comment options

gusty
Jul 25, 2019
Maintainer Author

I think we should create a parallel async wrapper type for Async that performs applicative operations in parallel by default.

So we can use it like this:

let x = async { return "1"} |> AsyncParallel
let y = async { return "2"} |> AsyncParallel
let arr = [|x;y|] |> sequence // AsyncParallel<string []>
let xy = arr |> AsyncParallel.run |> Async.RunSynchronously

Also

let x = async { return "1"} |> AsyncParallel
let y = async { return 2 } |> AsyncParallel
let tup = fun x y -> (x, y) <!> x <*> y
let xy = tup |> AsyncParallel.run |> Async.RunSynchronously

maybe we can add a specific workflow asyncP or pasync and a runSynchronously method:

let x = pasync { return "1"}
let y = pasync { return 2 }
let tup = fun x y -> (x, y) <!> x <*> y
let xy = tup |> AsyncParallel.RunSynchronously
You must be logged in to vote
0 replies
Comment options

gusty
Jan 21, 2020
Maintainer Author

I was thinking that another route is to add specific functions, like a traverseParallel which could be generic over monad transformers which are composed with Asyncs and it can take some arguments (maybe optionals) to specify the degree of parallelism.

Anyway, this doesn't prevent us to implement the wrapper above. It's just another way to achieve the same, I mean there is some overlap but it could be convenient in some situations.

Note that this is a bit more aligned with the current F# way, the problem with this approach is that you hit a limit when you want to do more stuff than sequence or traverse, like applicatives. It's interesting to note that applicative notation it's likely to be shipped in the next F# version, although it won't have implicit parallel semantics. How is the F# world going to deal with that? I don't know.

You must be logged in to vote
0 replies
Comment options

How will the applicative notation look in f#?

You must be logged in to vote
0 replies
Comment options

gusty
Jan 21, 2020
Maintainer Author

They will just add some keywords for CEs like and!.

You must be logged in to vote
0 replies
Comment options

Yes, that could turn out interesting for async behavior.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Ideas
Labels
None yet
Converted from issue

This discussion was converted from issue #36 on December 21, 2020 22:26.

AltStyle によって変換されたページ (->オリジナル) /