Splitting CHP

Riddle Me This

Q: When is a library not a library?
A: When it’s two, or three.

The CHP library has been growing progressively larger, and I have noticed something about a lot of the recent additions: several of them are entire modules that import Control.Concurrent.CHP. That is, they are extensions that build upon the existing library without requiring any access to the internal details of the library, and without being used or exported by the core of the library. This means that there is now a significant chunk of the library that I can safely break off and make its own library, titled chp-plus, that depends on the public interface of the chp library.

The Split

At first, I was resistant to the idea of splitting. I think it is more appealing to new users to have everything in one library rather than split between two; the latter suggests unwanted complexity. However, it is perhaps nice to have a smaller core library to offer, with further capabilities set aside — this was something that came up when comparing CHP to CML. The split delineates the core basic API (channels, barriers, enrollment and parallel) from the more sophisticated constructs that can sit on top of these (connectable, behaviours, and so on). The split also makes maintenance a little easier, by reducing the amount of functionality in the core library, and means that the core should develop slowly while the chp-plus package will likely develop more quickly. It also allows me to trim down the set of dependencies of the core library; CHP no longer depends on QuickCheck, for example (chp-plus does instead).

I decided to go ahead and make the split. I have taken the opportunity to remove the deprecated BroadcastChannels module, and the Utils module — the latter having been generalised and superseded by the Connect module. I have bumped up the chp version number to 2.0.0 as part of the change, and have released chp-plus 1.0.0 (as usual, all this is on hackage and can be installed using cabal). I suspect that chp-plus will fast outpace chp; aside from anything else, chp-plus can add new features without affecting chp, but any major changes to chp would probably require a chp-plus change too. For users, there should be little change required. Where previously you put “chp” in your build-depends field in cabal, you should now put “chp == 2.*, chp-plus == 1.*” or similar. You will need to transition from using the Utils module to Connect — most of the old operators are now encompassed in the new single <=> operator. Put a comment below if have any troubles.

The Third Package

Alongside these two packages, I’ve also split off a very small piece of functionality that has always been out of place in the CHP library. The LoopWhileT monad transformer adds simple easy looping support on top of an existing monad. You can place your whiles at the beginning of a block (generally known as a while loop), at the end (generally known as a do-while loop) and anywhere in the middle, including multiple times (generally known as do-while-do, and sadly lacking in almost all imperative languages). Each time a while is reached, the test is made, and if it fails the loop is broken, otherwise execution continues around the loop. This is all packaged up and documented in the loop-while package on Hackage if you’re interested in it, and is totally stand-alone. CHP now depends on it, mainly in order to provide a useful MonadCHP instance, but with cabal install this shouldn’t be a problem. I don’t expect loop-while to change much so you should only need to install it once and not worry about it.

Summary

CHP has now become two packages, chp-2.0.0 and chp-plus-1.0.0, with a side release of loop-while-1.0.0. I realise this will be slightly irksome for the existing users of the library to switch, but I hope that in the long run the split makes things easier for everyone. Not much code has been changed, only the library organisation, so the main thing you will need to adjust is your build system — and any use of the Utils module. I’ve also fixed some problems involving GHC 6.12, by using the deepseq library instead of parallel (as, confusingly, I only needed deepseq in CHP — for the strict send commands) because the release of parallel-2.x confused things a bit. This may cause problems if you are still using GHC 6.8, but I think it may be time that I stopped worrying about supporting GHC 6.8. If you have any troubles installing on GHC 6.10 or 6.12, just let me know.