Code Monkey home page Code Monkey logo

fluture's People

Contributors

0xflotus avatar aerlinger avatar amarshall avatar avaq avatar bhageena avatar blackwindforce avatar budokans avatar chip4 avatar cortopy avatar davidchambers avatar dependabot-preview[bot] avatar dependabot[bot] avatar dicearr avatar fr-sutiwo avatar franzwong avatar gitter-badger avatar greenkeeper[bot] avatar kreinholt avatar leighman avatar mickdekkers avatar porsager avatar stephanos avatar t-d-d avatar tetsuo avatar tusharmath avatar wms avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fluture's Issues

Feature Request: Add ChainPromise

NodeJS and a lot of libraries/frameworks use promises.
Hence, I often find myself chaining promises like this:

export const doSomething = () => {
  return Future.of(1)
    .chain(Future.fromPromise(() => /* a promise */ ))
    .chain(Future.fromPromise(() => /* a promise */ ))
    .chain(Future.fromPromise(() => /* a promise */ ))
}

I think if we have a .chainPromise function that allows user to write the above as:

export const doSomething = () => {
  return Future.of(1)
    .chainPromise(() => /* a promise */ )
    .chainPromise(() => /* a promise */ )
    .chainPromise(() => /* a promise */ )
}

It is pure sugar syntax but I think it will creates a lot of developer happiness.
Please let me know if this is something Fluture library should adopt and I can contribute the code for it.

Replace `Future` with `Future.Guarded`

See #17

  • Replace Future with Future.Guarded
  • Add a deprecation notice in Future.Guarded

Doing this would make Futures stateful by default. It seems like a very useful thing, but the statefulness doesn't sit well with me. Maybe I'm overlooking some consequences.

Rename fromPromise to encaseP

This question illustrates confusion about the fromPromise function which I think was, in part, caused by the naming of the function.

From Promise suggests that the function takes in a Promise and returns a Future. In fact it encases a function which returns a Promise to return a Future instead, very similar to the encase family of functions.

To make the similarities between the two families of functions more apparent, I'm thinking to rename fromPromise to encaseP. This would also naturally provide a name for encaseP(f, undefined): tryP(f).

Add Future.both

Future.of(1).both(Future.of(2));
//> Future.of([1, 2])

Future.of(1).both(Future.reject('kaputt'))
//> Future.reject('kaputt')

Future.reject('kaputt').both(Future.of(1))
//> Future.reject('kaputt')

Decide whether to flip arguments of fluent `.ap()`

I propose flipping the argument order of .ap() back to how it was pre-Fantasy Land 1.0, but we keep the argument order of ['fantasy-land/ap']() compliant with Fantasy Land 1.0 and later. That way we tackle two problems:

  1. The common complaint that the new .ap is awkward to use in fluent method chains.
  2. The fact that Ramda and other pre-FL1 libraries cannot dispatch to Fluture#ap. Fluture will become compliant to all versions of Fantasy Land with this change.

The counter-argument is that this may be confusing for two reasons:

  1. Fluture#ap will behave differently from other libraries' ap method. This may be a source of confusion, but it should also alleviate confusion depending on the users' expectation.
  2. Fluture#ap will behave differently from Fluture#fatansy-land/ap. I'm not sure if this is confusing, since nobody uses the latter directly.

Exception not throwing in Jest tests

Hi, I faced a very interesting issue when Fluture is ran in Jest tests:

// Jest test
// works
it('error is caught by Jest without another chain', () => {
  return new Promise((resolve, reject) => {
    return Future.of(1)
      .chain(() => { throw new Error('error') })
      .fork(reject, resolve)
  })
})

// does not work
it('error is not caught by Jest but instead timeouts', () => {
  return new Promise((resolve, reject) => {
    return Future.of(1)
      .chain(Future.fromPromise(Promise.resolve))
      .chain(() => { throw new Error('error') })
      .fork(reject, resolve)
  })
})

// works
it('error is caught by Jest when encapsulated in Future.try', () => {
  return new Promise((resolve, reject) => {
    return Future.of(1)
      .chain(Future.fromPromise(Promise.resolve))
      .chain(() => Future.try(() => { throw new Error('error') }))
      .fork(reject, resolve)
  })
})

In the second test case, the exception thrown in the Future is not bubbled up into the promise.
Hence the promise is not rejected and the test case timed out since nothing rejects or resolves it.
It seems like the Future has swallowed the exception!

Jest needs to catch the exceptions otherwise expect cannot work.
This issue is causing me to wrap all my expect statements in Future.try or else my test cases will not work.

I would like to know how Fluture re-throws the exception so that I can resolve this.
Any help to point out where in the source code for me to look into for possible solution is greatly appreciated too.

Future.finally should run even when the computation is cancelled

Since Future.finally is a simplified version of Future.hook (one where the cleanup does not depend on the resource), it would be better if they both behaved the same way under cancellation.

I propose that the finally-computation is started and cancelled immediately when the computation is cancelled, similar to how hook behaves.

Wrong docs for encase?

I sense that the docs for encase are wrong, but I wasn't able to write clearer docs. The problem is, that encase returns a function, not a Future. But I have hard times to put into writing what the new function does.

TypeError: Uncaught error: Future#fork expected the computation...

This looks similar to this issue in Futurize: Return void from computation

I'm getting this when I try to run the fourInstableFutures example from the Readme.md.

Here's the original code that throws the error (copied and pasted from Readme.md):

const fourInstableFutures = Array.from(Array(4).keys()).map(
  i => Future(
    (rej, res) => setTimeout(
      () => Math.random() > 0.8 ? rej('failed') : res(i),
      20
    )
  )
);

const stabalizedFutures = fourInstableFutures.map(Future.fold(S.Left, S.Right))

Future.parallel(2, stabalizedFutures).fork(console.error, console.log);

Putting void in front of setTimeout makes the error go away:

const fourInstableFutures = Array.from(Array(4).keys()).map(
  i => Future(
    (rej, res) => void setTimeout(
      () => Math.random() > 0.8 ? rej('failed') : res(i),
      20
    )
  )
);

const stabalizedFutures = fourInstableFutures.map(Future.fold(S.Left, S.Right))

Future.parallel(2, stabalizedFutures).fork(console.error, console.log);

Unit test uncovered code

The new ES6 code is not completely covered by the old unit tests. In attaining 100% coverage, we should be sure to test for the following:

  • the behavior of never, especially with regards to race
  • the optimized implementations of transformations which live on Rejected, Resolved and Never.

Threading state

I'm trying to manually thread some state through chained futures:

F.of({ state })
      .chain(({ state }) => F.of({ state, ...someFuture(state).value(x => x) }))
      .chain(({ state }) => F.of({ state, ...someOtherFuture(state).value(x => x) })) 
      .fork(console.log, console.log);

My thought is that with this approach and someFuture() and someOtherFuture returning { state: "new"} this would essentially replace the state as if a put was ran in a State monad.

The problem here is that clearly nested Futures are not supposed to work like this as I figure F.of() evaluates its argument strictly which returns the actual function object rather than the result of .value().

Do you have thoughts on how to accomplish this kind of explicit state threading?

Add Future.and

Future.of(1).and(Future.of(2));
//> Future.of(2)

Future.of(1).and(Future.reject('kaputt'))
//> Future.reject('kaputt')

Future.reject('kaputt').and(Future.of(1))
//> Future.reject('kaputt')

Implement Alternative using race/never

Now that race has a special case for Never instances, we can implement lawful Alternative using race and never. This would mean that conversion to the ConcurrentFuture would only be necessary to get parallel ap behavior.

Allow wrapping node functions that expect more than one result argument.

I might be totally missing something, but I'm having trouble wrapping fs.read with Future.node. I think the reason is that fs.read expects a callback with three arguments: err, bytesRead, and the data buffer. When I console.log ...args in the chained function called, it only shows bytesRead in the array of arguments.

Am I way off? If not, is there anyway around this?

Implement #done(callback) - a counterpart to .node()

Hi there,

Just came accross Fluture and giving it a try to try and bring some functional tricks inside an existing node framework (seneca).

In the way that there is .node() abiding by the NodeJS convention of (err, results) maybe there should be a version of .fork() which allows to consume the future by executing a node callback(err, results)?

Maybe a .done() ?

Cheers!

Jun

Update to FantasyLand 3.0

I think the changes to FantasyLand do not affect Fluture. Therefore I believe Fluture already support 3.0.

To fix this issue, the README should be updated to indicate support for FL 3.0. I think it may be better to indicate that Fluture supports FantasyLand 1.0, 2.0 and 3.0.

Cancellation has a memory leak

The problem occurs in Future$fork and Future$chain/Future$chainRej. Both functions export or import the clear (resource disposal) function into another scope, causing references to be kept until clear is garbage-collected. This is killing for long running processes.

5.0.0 Checklist

  • Fix #71 (Merge #73)
  • Remove Future.cast (Merge #75)
  • Remove Future.fromForkable (Merge #75)
  • Fix argument order of Future.and (Merge #74)
  • Find the reason for, and fix the problem causing unhandledRejection before the unit tests run

Interoperable do

I thought I'd open an issue to track progress on this and maybe bring in some fantasy-land veterans to advise. As pointed out by @Avaq in #82

Most do implementations fail when a Future is forked twice, because of stateful generators. I thought of a do which fixes that, but it has other problems associated with Functors of multiple values (like Array). :(

Multi arity .node()

Hi there,

I would find it useful to be able to call node style callback functions with one or several arguments.

For instance in the current example:

Future.node(done => fs.readFile('package.json', 'utf8', done))

Is a future with no arguments, but it would be useful to be able to wrap fs.readFile into a future of one or two arguments.

Cheers,

Jun

Update documentation

  • new functions (isNever, first)
  • aliases (lastly, go, attempt)
  • dropped methods (cache, hook)
  • stack and recursion safety
  • environment requirements
    • ES5 with (polyfilled): Object.create, Object.assign, Array.isArray; or
    • Node 7 compatible ES6 environment with module support

.thread() or how I reinvented a broken .map()

I think that the thread higher order function described in #82

const thread = (left, right, future) => function*(){ return S.either(left, right, yield F.fold(S.Left, S.Right, future))}

F.of( {state} )
      .chain(({ state }) => F.do(thread(left => `Oh no! ${left}`, some => ({ state, some }), someFuture(state))))
      .chain(({ state, some }) => F.do(thread(left => `Oh no! ${left}`, other => ({ state, some, other }), someOtherFuture(some))))
  .fork(console.log, console.log)

defines some sort of mini monad transformer which allows to thread an Either Monad with the Fluture monad. And I guess this makes the code above some kind of Keisli composition for 2 monads? My theory doesn't hold up yet there...

I'm thinking that there's probably a well known interface/type class for this, maybe requiring monad transformers and lifting (as discussed in mattbierner/akh#31) ?

It could be a nice ad-hoc short term addition to have a .thread() operation in Fluture, but there's probably a more composable way?

Fail-fast curried functions

Fail as soon as the invalid argument is provided to the curried function.

  • ap
  • map
  • bimap
  • chain
  • and
  • rejectAfter
  • chainRej
  • mapRej
  • swap
  • fork
  • race
  • or
  • fold
  • hook
  • finally
  • after
  • cast
  • encase
  • encase2
  • encase3
  • parallel
  • value

Void

very many bugs

EDIT: Bad practical joke

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.