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

Adds Task.do #128

Merged
merged 3 commits into from Jul 10, 2017

Conversation

Projects
None yet
3 participants
@framp
Contributor

framp commented Jun 21, 2017

As per issue #111.
I've seen it's scheduled for post-2.0 but I had the code lying around and I love my (syntactic) sugar.

It can be used like this:

Task.do(function *() {
  const a = yield delay(10); 
  const b = yield delay(11); 
  const c = yield Task.of(5);
  return Task.of(a + b + c + 4);
})

Right now all the yielded / returned values need to be an instance of Task and behave like Haskell's bind, while in JavaScript (async/await, coroutines) values get promisified if they're not Promises.

I personally think it's confusing to promisify things implicitly and caused a few misunderstanding while teaching newcomers.
What do you think about it?

EDIT: I forgot to say, I'm not sure I followed the right convention for the type annotation, so that may need some fixing

Thanks

framp added some commits Jun 21, 2017

(new base tests) Adds Task.do
`Task.do` accepts a Task-emitting Generator and returns a Task which
will execute all the tasks and pass back the appropriate values to the
Generator.

Fixes #111
@robotlolita

This comment has been minimized.

Show comment
Hide comment
@robotlolita

robotlolita Jun 21, 2017

Member

Hey, thanks :)

I agree on the part of not trying to reify values into tasks implicitly. I do think this is better defined in terms of the Monad interface, though.

That way, given:

const  x = Task.do(function* () {
  const a = yield taskA;
  const b = yield taskB;
  return Task.of(a + b);
});

Gets translated to:

const x = taskA.chain(a => {
  return taskB.chain(b => {
    return Task.of(a + b);
  });
});

This ensures we respect things like external cancellation, which would be a bit more difficult doing this way because there's a bit of state that needs to be tracked.

Member

robotlolita commented Jun 21, 2017

Hey, thanks :)

I agree on the part of not trying to reify values into tasks implicitly. I do think this is better defined in terms of the Monad interface, though.

That way, given:

const  x = Task.do(function* () {
  const a = yield taskA;
  const b = yield taskB;
  return Task.of(a + b);
});

Gets translated to:

const x = taskA.chain(a => {
  return taskB.chain(b => {
    return Task.of(a + b);
  });
});

This ensures we respect things like external cancellation, which would be a bit more difficult doing this way because there's a bit of state that needs to be tracked.

(fix base) Replaces Task.do implementation
Task.do now uses Task's Monad interface
@framp

This comment has been minimized.

Show comment
Hide comment
@framp

framp Jun 21, 2017

Contributor

Sure thing, updated to use the monadic interface

Contributor

framp commented Jun 21, 2017

Sure thing, updated to use the monadic interface

@robotlolita

This comment has been minimized.

Show comment
Hide comment
@robotlolita

robotlolita Jul 8, 2017

Member

Sorry for taking so long to review the changes Orz I'll try to do it this weekend

Member

robotlolita commented Jul 8, 2017

Sorry for taking so long to review the changes Orz I'll try to do it this weekend

@robotlolita robotlolita merged commit 2078b05 into origamitower:master Jul 10, 2017

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
coverage/coveralls Coverage increased (+0.08%) to 89.833%
Details
@robotlolita

This comment has been minimized.

Show comment
Hide comment
@robotlolita

robotlolita Jul 10, 2017

Member

Thanksies :)

Member

robotlolita commented Jul 10, 2017

Thanksies :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment