Skip to content

Allow cancellation of computations forked with runAff #52

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

Merged
merged 1 commit into from
Jun 9, 2016

Conversation

sardonicpresence
Copy link
Contributor

At present, in order to have a cancellable asynchronous computation it seems you forego both success and error callbacks in the call to forkAff, the only function to return a Canceler.

Particularly given that in the JavaScript runAff already returns a Canceler I saw no reason not to include a version returning it in PureScript.

In the process of adding a test for the above, I was inconvenienced by the inability to

do
  c <- runAff throwException (const (pure unit)) a
  launchAff $ cancel c (error msg)

due to the odd coersion of effect records in launchAff so I thought I'd propose a change there as well.

I'm assuming that the breaking nature of these changes will be contentious at least but thought I'd start here.

where
liftEx :: Aff e a -> Aff (err :: EXCEPTION | e) a
liftEx = _unsafeInterleaveAff
launchAff :: forall e a. Aff (err :: EXCEPTION | e) a -> Eff (err :: EXCEPTION | e) Unit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not modify this to return a canceller, to? User can always ignore a canceler if it's not necessary. Also this would allow you to delete the helper function runAff_.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason other than to minimise changes to the API. I certainly don't object to your suggestion.
Thanks for taking a look btw.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this will be included in a breaking release anyway (due to 0.9 updates), it's a good chance to clean up things like this. I'd rather a user void a return value they don't want, then not have the option (or multiply the surface area of the API).

@jdegoes
Copy link
Contributor

jdegoes commented Jun 3, 2016

@sardonicpresence Howdy there, waiting for your feedback above. Thanks for the PR, by the way!

@sardonicpresence
Copy link
Contributor Author

Actioned review comments and re-based (hope that's reasonable etiquette).

where
liftEx :: Aff e a -> Aff (err :: EXCEPTION | e) a
liftEx = _unsafeInterleaveAff
launchAff :: forall e a. Aff (err :: EXCEPTION | e) a -> Eff (err :: EXCEPTION | e) (Canceler (err :: EXCEPTION | e))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes look great. This is the only one I'm concerned about. Technically, an EXCEPTION effect type in an Aff doesn't mean anything, since Aff doesn't throw exceptions in a way that can be caught via the same mechanism for Eff.

The intention is that you can lift any Eff with EXCEPTION into an Aff, and it drops the EXCEPTION; and that you can lower any Aff into an Eff and it adds EXCEPTION. That's not quite precise but I think it's probably the best we can do.

Is there some other way of addressing your need for this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be frank I really struggle to see the utility of the effect record mechanism in Purescript generally.

I understand what you saying in regards to EXCEPTION not making sense in Aff, in fact this is the first instance I think I've encountered where rejecting certain effects makes sense like this. However runAff would still allow you to run an Aff with an EXCEPTION effect for example.

I think what you actually want is probably runAff to be able to declare that the effects in the Eff monads are a superset of those in the Aff monad but I don't believe that's currently possible in the language. I'm not sure what would be correct for the Canceler.

I hadn't thought of liftEff' as a kind of dual for launchAff; I'll have a think as to whether I can make use of it though I'm concerned by the use of Either as opposed to calling the error callback at a glance.

I'll have another stab at it tonight.

@sardonicpresence
Copy link
Contributor Author

Alright I reverted the objectionable change, requiring further coercing in launchAff. If we could be more expressive about relationships between effect records I'd do differently but there we are.

I've also re-based once again.

@jdegoes
Copy link
Contributor

jdegoes commented Jun 9, 2016

@sardonicpresence Great work. Thanks! 🙏

@jdegoes jdegoes merged commit f9b8901 into purescript-contrib:master Jun 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants