-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change apply to prefer concurrent execution #151
Comments
In the case of an infix symbol, the arguments should be flipped: -val ( <*> ): Job<'x> -> Job<'x -> 'y> -> Job<'y>
+val ( <*> ): Job<'x -> 'y> -> Job<'x> -> Job<'y> Hmm... I think there are good points in this proposal: The current use of There is an important difference between concurrent and parallel programming. In concurrent programming one specifically embraces non-determinism (the order of events is non-deterministic and is allowed to affect the end result) while in parallel programming the goal is to be deterministic: given a parallel program, simply running it sequentially should give the same result. The current The primary feature of In Hopac, The case with |
Thanks for catching the infix miss. I understand where you are going with the concurrent vs. parallel distinction, and can see where sequential would be a better default, with some way to buy in to concurrent/parallel execution. If Revised Diff: module Job =
val apply: Job<'x> -> Job<'x -> 'y> -> Job<'y> //no change
+ val applyParallel: Job<'x> -> Job<'x -> 'y> -> Job<'y>
+ val combineSequential: Job<'x> -> Job<'y> -> Job<'x * 'y>
+ val combineParallel: Job<'x> -> Job<'y> -> Job<'x * 'y>
module Alt =
// Warnings to be added in XML doc, similar to <+> now.
+ val apply: Alt<'x> -> Alt<'x -> 'y> -> Alt<'y>
+ val combine: Alt<'x> -> Alt<'y> -> Alt<'x * 'y>
module Promise =
// Uses parallel semantics
+ val apply: Promise<'x> -> Promise<'x -> 'y> -> Promise<'y>
+ val combine: Promise<'x> -> Promise<'y> -> Promise<'x * 'y>
module Infixes =
- val ( <&> ): Job<'x> -> Job<'y> -> Job<'x * 'y>
- val ( <*> ): Job<'x> -> Job<'y> -> Job<'x * 'y>
- val ( <+> ): Alt<'x> -> Alt<'y> -> Alt<'x * 'y>
// Give precedence to Promise
+ val ( <!> ): ('x -> 'y) -> Promise<'x> -> Promise<'y>
+ val ( <*> ): Promise<'x -> 'y> -> Promise<'x> -> Promise<'y>
+ val ( <^> ): ('x -> 'y) -> Job<'x> -> Job<'y>
// Sequential apply (similar to current definition)
+ val ( <&> ): Job<'x -> 'y> -> Job<'x> -> Job<'y>
// Parallel apply (ParTuple, then map)
+ val ( <+> ): Job<'x -> 'y> -> Job<'x> -> Job<'y> Another option for the |
A few random thoughts. I believe there are use cases for all of
semantics of applicative composition and for all the types Also, Having sub-modules for different semantics would allow all the relevant combinations to be provided. |
The current implementation of
Job.apply
is equivalent tox2yJ >>= fun x2y -> xJ >>- x2y
, which means thatx2yJ
is resolved first, thenxJ
is resolved. Once both are resolved, the result ofxJ
is applied to the result ofx2yJ
. This is explicitly sequential.Being a concurrent library, the default for the apply function ought to be a concurrent implementation. We currently have an operator
<*> : Job<'x> -> Job<'y> -> Job<'x * 'y>
. Thus a concurrent implementation of apply could be defined asx2yJ <*> xJ >>- fun (x2y, x) -> x2y x
.Changes:
Job.combineSequential
andJob.combineConcurrent
as replacements for<&>
and<*>
, respectively<!>
as an alias forJob.map
. Follows convention for F# map operator.<*>
to be a concurrent apply with aliasJob.apply
. This brings the use of this operator more inline with common F# or Haskell usage (as an equivalent to apply)<&>
to be a sequential apply with aliasJob.applySequential
The story for
Alt
s is a little bit more interesting. In order to wait for twoAlt
s to become ready simultaneously, we do a concurrent wait for either followed by a wait for the second one. This means that if the combinedAlt
is nacked after oneAlt
has been committed to, but while the otherAlt
is still running, we only have the ability to nack the runningAlt
. There is no great way to commit to both only when both are ready. This issue doesn't suggest a fix for that.Alt.combine
as replacement for<+>
<+>
to be a concurrent apply with aliasAlt.apply
.Old API:
New API:
API Diff:
The text was updated successfully, but these errors were encountered: