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

Enable type-level distinctions between operations that thread state and those that don’t. #293

Open
patrickt opened this issue Oct 23, 2019 · 10 comments
Assignees
Labels
enhancement New feature or request

Comments

@patrickt
Copy link
Collaborator

We removed the Resource effect in #268 because of its unlawful interactions with the State effect. This was the right move, but it is also a bummer, because the Resource effect is extremely useful.

What would be ideal is a system like polysemy’s Tactics module, which used in concert with Resource and the withLowerToIO system provided by their forklift implementation. Failing that, it would be ideal to have some type-level mechanism that rejects calls to functions like get and put inside a finally block:

finally :: (Has Resource sig, Carrier sig m, IsStatelessIn n m) 
  => m a
  -> n a
  -> m a

where this hypothetical IsStatelessIn construct is fulfilled by Reader but not by State. Or something. Either approach would be acceptable to me; that would enable us to deprecate fused-effects-exceptions and welcome Resource back into the fold.

@patrickt patrickt added the enhancement New feature or request label Oct 23, 2019
@jkachmar
Copy link
Contributor

I was following along with some of the polysemy work on Tactics and Strategy and remembered some threads that may be useful if y'all end up going down that route:

@KingoftheHomeless discusses the Final and Lift' effects for embedding higher order effects

@KingoftheHomeless PR's these effects, along with the Strategy environment for making this higher-order effect weaving easier

Strategy and Final have since been merged into polysemy, but most of the history and discussion is in polysemy-zoo IIRC.

@jkachmar
Copy link
Contributor

Notably, asyncToIOFinal (which uses Strategy) obviates the need for all the Forklift machinery and so avoids the additional thread + polling machinery.

@robrix
Copy link
Collaborator

robrix commented Oct 25, 2019

I believe #296 gives us this capability.

@patrickt
Copy link
Collaborator Author

296 will close this, yes.

@ProofOfKeags
Copy link
Contributor

ProofOfKeags commented Oct 9, 2020

So it looks like you said #296 would give us this capability but that PR was ultimately closed. I, like many others, are coming to this for the desire to be able to asyncify things that are effectively Identity wrappers. All the issues talking about this are dead-ended in some way. What's the state of the art knowledge on how to deal with this?

EDIT: the desire is to retain the ability to have multiple interpretations, none of them need to have state in the context functor though

@KingoftheHomeless
Copy link

KingoftheHomeless commented Oct 12, 2020

@ProofOfKeags At the risk of sounding full of myself, the state of the art on this would be the approach taken by my newly released library: in-other-words. One thing the approach does is that an interpreter may introduce constraints that restrict what other interpreters may be used together with it. This gives you what you're looking for: you can have an effect for concurrency, since its interpreter can place restrictions on what other interpreters you may use to guarantee that it's able to unlift to IO.

@ProofOfKeags
Copy link
Contributor

@KingoftheHomeless Cool that you were able to solve this. Can't say I'm a fan of trying to switch effect systems as a result of this, but I may still attempt to do so at some point. I was hoping I'd be able to patch fused-effects or restrict myself to some subset of the library in order to do be able to use async effects.

@robrix
Copy link
Collaborator

robrix commented Oct 12, 2020

It’s possible we could take the same approach in fused-effects (haven’t looked into it yet), but failing that, it’s also possible to do what I’m doing in starlight & isometry and just… drop any state changes happening on the background thread.

That’s not ideal, and it’s regrettably silent, but it does allow for sensible use if you keep that in mind: basically, you get to make and observe any sort of local state changes you want in the forked thread, so long as you remember that they’re not going to be magically synchronized back to the forking thread.

Further, you can also use this sort of thing to set up some sort of synchronization mechanism to transport state changes across threads; I’m doing that in those projects, too.

So all is not lost!

@ProofOfKeags
Copy link
Contributor

I think this is definitely superior to straight up not having a polymorphic async effect. I think a big warning on the tin that says that the pure construction of state/writer won't propagate over async effects is something that most people would have the capacity to understand.

@patrickt
Copy link
Collaborator Author

In fused-effects-exceptions there’s a carrier for State that uses an IORef and thus doesn’t lose information. We could add one for Writer as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants