Skip to content
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

Expose non monadic version of Future #44

Closed
safareli opened this issue Nov 7, 2016 · 10 comments
Closed

Expose non monadic version of Future #44

safareli opened this issue Nov 7, 2016 · 10 comments
Assignees

Comments

@safareli
Copy link

safareli commented Nov 7, 2016

It will be nice to expose non monadic version of Future for which ap would be parallel.
This version could also implement Alternative where alt would be race

@Avaq
Copy link
Member

Avaq commented Dec 27, 2016

ℹ️ I'm working on this.

@Avaq Avaq self-assigned this Dec 27, 2016
@Avaq Avaq modified the milestone: 5.0.0 Jan 7, 2017
@Avaq Avaq removed this from the 5.0.0 milestone Jan 18, 2017
@Avaq
Copy link
Member

Avaq commented Jan 18, 2017

I'm looking into developing this as its own package, extending Fluture with an optional Parallel structure. Some of Flutures core functionality will also be separated out to serve as a base for both packages.

@safareli
Copy link
Author

@Avaq why?

So you are planning to have 3 repos like this?:

  • Avaq/Fluture-core
  • Avaq/Fluture
  • Avaq/FluturePar

@Avaq
Copy link
Member

Avaq commented Jan 18, 2017

why?

In writing a detailed response about my reasons, I realized there may be some issues with this approach (circular dependencies, shared code). I'm going to drop the idea, and keep it in the same package.

@safareli
Copy link
Author

safareli commented Jan 18, 2017

After discussing this offline, here is what we came to:

As there is Concurrently in haskell:

newtype Concurrently a = Concurrently { runConcurrently :: IO a }

instance Functor Concurrently where
  fmap f (Concurrently a) = Concurrently $ f <$> a

instance Applicative Concurrently where
  pure = Concurrently . return
  Concurrently fs <*> Concurrently as =
    Concurrently $ (\(f, a) -> f a) <$> concurrently fs as

instance Alternative Concurrently where
  empty = Concurrently $ forever (threadDelay maxBound)
  Concurrently as <|> Concurrently bs =
    Concurrently $ either id id <$> race as bs

We could have something like this:

const mkConcurrently = (TaskRep, concurrently, race, zero) => {
  const Concurrently = daggy.tagged('run')
  Concurrently[fl.zero] = zero
  Concurrently[fl.of] = (a) => Concurrently(TaskRep[fl.of](a))
  Object.assign(Concurrently.prototype, {
    [fl.map](f) {
      return Concurrently(this.run[fl.map](f))
    },
    [fl.ap](a) {
      return Concurrently(concurrently(this.run,a))
    },
    [fl.alt](a) {
      return Concurrently(race(this.run, a))
    },
  })
  return Concurrently
}

Which could be used with any Task/Future/whatever.

Example with Fluture:

const Par  =  mkConcurrently(
  Fluture, 
  (a,b)  => a.par(b),
  (a,b)  => a.race(b),
  Fluture.never
)

Par(Fluture.after(300, 1))[fl.alt](Par(Future.of(2)))
  .run.fork(log, log)

@safareli
Copy link
Author

I think using names in spirit of purescript-parallel would be better:

-const Concurrently = daggy.tagged('run')
+const Parallel = daggy.tagged('sequential')
Par(Fluture.after(300, 1))[fl.alt](Par(Future.of(2)))
-  .run.fork(log, log)
+  .sequential.fork(log, log)

@Avaq
Copy link
Member

Avaq commented Jan 28, 2017

I created https://github.com/fluture-js/concurrify for this purpose. I'm working on the implementation now. Your thoughts?

@safareli
Copy link
Author

safareli commented Jan 28, 2017

That's nice!

what you think about moving that to FantasyLand, as fantasy-concurrify for example?

@Avaq
Copy link
Member

Avaq commented Jan 28, 2017

I'm creating it with the design decisions made for Fluture in mind. I'm not sure if it's too opinionated to host under FantasyLand (eg; the inclusion of @@type). Let's discuss it there: fluture-js/concurrify#1

@Avaq
Copy link
Member

Avaq commented Feb 10, 2017

The next step, I think, would be to depend on concurrify and expose Future.Par :: Future a b -> ParallelFuture a b and Future.seq :: ParallelFuture a b -> Future a b.

Avaq added a commit that referenced this issue Feb 13, 2017
Adds the following functions:

* Future.Par :: (Applicative f, Alternative (m f)) => f a -> m f a
* Adds Future.seq :: Applicative f => Par f a -> f a
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 13, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following functions:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: () -> Future a a

Closes #44
Avaq added a commit that referenced this issue Feb 14, 2017
Adds the following exports:

* Future.Par :: Future a b -> ConcurrentFuture a b
* Future.seq :: ConcurrentFuture a b -> Future a b
* Future.never :: Future a a

Closes #44
@Avaq Avaq closed this as completed in 250180e Feb 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants