
Duncan Coutts
Henning raises a good point:
writeFile path . process =<< readFile path
This is an excellent motivating example for why the Haskell committee included locking in the first place.
Indeed. It’s a long time ago, but I dimly remember discussions on these lines. Certainly there was an issue with lazy IO (attempting to make it morally referentially transparent), but one of the arguments was that, ideally, things like readFile should behave as if they were atomic, perhaps by means of shadow pages. So in the ideal semantics, the above programme would do what it appears to do, but there were complaints about efficiency and difficulty of implementation, so we settled on the locking approach (with a nod towards the difficulty of implementation in Windows). Now, as far as I am concerned, the difficulties implementing the ideal case are flaws in the operating systems, and should not, therefore, inform the design of Haskell. And the normal case should be the uncomplicated, as near to functional as possible one. So, short of implementing shadow pages, the locking should remain. * * * For the cases where it is a problem, we need new modes, don’t we? data IOMOde = ReadMode -- we expect the file to remain constant -- until closed | WriteMode -- we expect the file to end up with -- exactly the contents we put in it | AppendMode -- old contents + what we write | ReadWriteMode -- more complex to describe, but -- no one else gets to mess with -- it | … -- more modes allowing multiple writers. I hesitate to fill in names for the other cases, because I have little experience of using them. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk