-
Notifications
You must be signed in to change notification settings - Fork 104
-
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?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 6 comments
-
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.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
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
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 3
-
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.
Beta Was this translation helpful? Give feedback.
All reactions
-
How will the applicative notation look in f#?
Beta Was this translation helpful? Give feedback.
All reactions
-
They will just add some keywords for CEs like and!
.
Beta Was this translation helpful? Give feedback.
All reactions
-
Yes, that could turn out interesting for async behavior.
Beta Was this translation helpful? Give feedback.