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

figure out allowing mutable vectors to handle monad stacks #65

Closed
cartazio opened this issue Dec 31, 2014 · 14 comments
Closed

figure out allowing mutable vectors to handle monad stacks #65

cartazio opened this issue Dec 31, 2014 · 14 comments

Comments

@cartazio
Copy link
Contributor

possibly by eg a breaking change to the api for 0.11 (or more likely 0.12) that either
a) uses Monad-ST or
b) rethinks PrmMonad and the primitive package

I think this should be on the table for 0.12, though its something that should be contemplated for 0.11

@snoyberg
Copy link

I regularly do this by using MonadBase from transformers-base. For example, Data.Conduit.Zlib.

@cartazio
Copy link
Contributor Author

huh, i'll have to stare at it, but I think that MonadST class is just general enough for this use case, while still allowing much of the current PrimMonad use cases to remain recoverable

@snoyberg
Copy link

Actually, I misunderstood your first comment and didn't realize monad-st was a package providing the MonadST typeclass (thought you were referring to Control.Monad.ST). I quite like that approach. Just to flesh out the design space a bit, another similar package is monad-primitive.

I'm interested in seeing this move forward, but also concerned about breaking backwards compatibility. I have a feeling that there are ways of doing this that greatly minimize breakage, but I need to think about it a bit more.

snoyberg added a commit to snoyberg/primitive that referenced this issue Dec 31, 2014
@snoyberg
Copy link

Have a look at:

snoyberg/primitive@0522839

I realize that the only problematic aspect of PrimMonad is the internal method, which requires that we be able to express an action fully in terms of a state transformer. PrimState and primitive apply to all transformers, and are really just a longer way of specifying MonadST. So I split off the internal method into its own typeclass, for which only IO and ST are instances, and provided the same MonadTrans instance for PrimMonad as MonadST has. With this change, the rest of primitive and all of vector compile without any code changes.

The breakage introduced here is:

  • Existing PrimMonad instances in the world would need to be changed. I wouldn't be surprised if there are exactly 0 of those.
  • Usages of internal in the world will need to change their typeclass constraint. Given that this didn't occur once in vector, it may not be something people ever do. (Not too surprising given all the helper functions in Control.Monad.Primitive.)
  • A new dependency is added on transformers. (Not technically a breakage, but worth mentioning.)

While I think the MonadST is the more elegant solution here, pragmatism of avoiding breakage pushes me towards recommending this change instead.

@cartazio
Copy link
Contributor Author

i'll have to digest these ideas, but its worth noting that anything that is generic over MonadST m can be instantiated to IO or ST monad, and thence the primMonad Api can be used as before. That is, anything using MonadST m can ALWAYS be downgraded via PrimMonad m => IO a -> m a or something along those lines.

@cartazio
Copy link
Contributor Author

theres enough breaking changes landing in 0.11 and subsequently to improve the library, that I dont think theres a clear argument that we can/should make breaking changes to primitive! Additionally, the PrimMonad api as it currently exists can be used to write PrimMonad m,MonadST ms => m a -> ms a, and its inverse is also definable with similar ease via liftST.

our Mutable vector apis have been crippled for years, i'm not sure that your proposed change is as the right point to do the breaking change. (namely, it pushes the breakage to primMonad users rather than Mutable Vector Users). Granted, thats a lot more visible breakage, and I totally agree with that

@cartazio
Copy link
Contributor Author

cartazio commented Jan 1, 2015

I think the MonadST style api can still expose that exact same "raw interface"

a Control.Primitive.Unsafe could import the internals of the ST monad and define
primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
by taking advantage of the ST constructors

newtype ST s a = ST (STRep s a)
type STRep s a = State# s -> (# State# s, a #)

@snoyberg
Copy link

snoyberg commented Jan 1, 2015

and its inverse is also definable with similar ease via liftST

I don't believe that's true, can you show what that looks like? I don't know how you would write something that allows you to convert a ReadterT IO into an IO.

I'm not sure which other breaking changes are planned, but I'm typically very hesitant about just heaping on extra breakage because we're already breaking other things.

@cartazio
Copy link
Contributor Author

cartazio commented Jan 1, 2015

oh, i was thinking a bit tooo impredicatively, that I could essentially do (forall m . MonadST m=> m a )-> IO a or the like, because most programs i'm concerned with are polymorphic in this monadthingy

anyways, @dolio has sold me on the upgrading PrimMonad, lets make it happen! :)
(though i think there should be some back and forth on that too)

@snoyberg
Copy link

snoyberg commented Jan 1, 2015

I thought that might have been what you were thinking of, which comes out
to the same as just specializing to ST if I'm not mistaken.

Anyway, how should we proceed? I can certainly send a pull request with the
changes I made so far and we can iterate on that.

On Thu, Jan 1, 2015, 8:38 PM Carter Tazio Schonwald <
notifications@github.com> wrote:

oh, i was thinking a bit tooo impredicatively, that I could essentially do (forall
m . MonadST m=> m a )-> IO a or the like

anyways, @dolio https://github.com/dolio has sold me on the upgrading
PrimMonad, lets make it happen! :)
(though i think there should be some back and forth on that too)


Reply to this email directly or view it on GitHub
#65 (comment).

@cartazio
Copy link
Contributor Author

cartazio commented Jan 1, 2015

a) yup! (which is kinda a subtle thing to grasp i think)

b) thats probably a good way to role, though its ultimately @dolio 's call. but seems like a concrete starting point for making stuff happen. I suspect we'll have to bikeshed over the primmonadinternal class name or whatever

@cartazio
Copy link
Contributor Author

cartazio commented Jan 1, 2015

@snoyberg to clarify: if we can cut a new major bump on primmonad for this in the next few days, i'm all for it

@snoyberg
Copy link

snoyberg commented Jan 1, 2015

OK, I opened a pull request on this.

On Thu, Jan 1, 2015, 11:43 PM Carter Tazio Schonwald <
notifications@github.com> wrote:

@snoyberg https://github.com/snoyberg to clarify: if we can cut a new
major bump on primmonad for this in the next few days, i'm all for it


Reply to this email directly or view it on GitHub
#65 (comment).

snoyberg added a commit to snoyberg/primitive that referenced this issue Jan 2, 2015
snoyberg added a commit to snoyberg/primitive that referenced this issue Jan 7, 2015
dolio added a commit to haskell/primitive that referenced this issue Feb 11, 2015
@dolio
Copy link
Contributor

dolio commented Jul 14, 2015

If I'm not mistaken, this was addressed when we split PrimMonad.

@dolio dolio closed this as completed Jul 14, 2015
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

3 participants