darcs patch: add withFile and withBinaryFile (#966)

Thu Oct 26 01:10:44 BST 2006 Ross Paterson

On 10/25/06, Ross Paterson
Thu Oct 26 01:10:44 BST 2006 Ross Paterson
* add withFile and withBinaryFile (#966) To be discussed on the libraries list until Thursday 9th November 2006.
These functions are fairly small, but they're worth naming because they wrap up a pattern that should be encouraged.
I think this bikeshed would be nice in red. (Or: why would it take two weeks to discuss this?)

On Wed, Oct 25, 2006 at 11:16:25PM -0400, Samuel Bronson wrote:
On 10/25/06, Ross Paterson
wrote: Thu Oct 26 01:10:44 BST 2006 Ross Paterson
* add withFile and withBinaryFile (#966) To be discussed on the libraries list until Thursday 9th November 2006.
These functions are fairly small, but they're worth naming because they wrap up a pattern that should be encouraged.
I think this bikeshed would be nice in red. (Or: why would it take two weeks to discuss this?)
OK, I should have phrased that as "Please make any comments on the libraries list by <date>" (because that's when I'm committing the patch if I don't hear any objections). It's an experiment with the new process. So do you have a comment?

On 10/26/06, Ross Paterson
On Wed, Oct 25, 2006 at 11:16:25PM -0400, Samuel Bronson wrote:
On 10/25/06, Ross Paterson
wrote: Thu Oct 26 01:10:44 BST 2006 Ross Paterson
* add withFile and withBinaryFile (#966) To be discussed on the libraries list until Thursday 9th November 2006.
These functions are fairly small, but they're worth naming because they wrap up a pattern that should be encouraged.
I think this bikeshed would be nice in red. (Or: why would it take two weeks to discuss this?)
OK, I should have phrased that as "Please make any comments on the libraries list by <date>" (because that's when I'm committing the patch if I don't hear any objections). It's an experiment with the new process.
So do you have a comment?
My only comment is that this is a Good Thing(tm). Back when I did a lot of lisp I remember someone telling me, "Figure out the correct way to open a file, do something with it, catch any exceptions, clean up and pass on any exceptions. Then, once you know how, write a macro and never do it by hand again!" (Common Lisp does already have a macro just like this, but the point remains.) Thanks! Jason

On Thu, Oct 26, 2006 at 01:15:11AM +0100, Ross Paterson wrote:
hunk ./System/IO.hs 369 +-- | @'withFile' name mode act@ opens a file using 'openFile' and passes +-- the resulting handle to the computation @act@. The handle will be +-- closed on exit from 'withFile', whether by normal termination or by +-- raising an exception. +withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r +withFile name mode = bracket (openFile name mode) hClose
I like this function (and use ones like it all the time in darcs), but do wonder whether it might be possible to ensure that the Handle doesn't escape, which would make it ultra-cool. I can't see how to do this, except to put the third argument into another monad and use a phantom type, which would be highly awkward, to say the least. But if there were a pretty approach, it would be very fancy. In case I've been too vague, what I mean is that I'd like it if one could ensure that code such as withFile "filename" ReadMode return >>= hGetContents statically fails, rather than failing at runtime with a file handle closed exception. I know this is a stupid thing for the programmer to do, but it's nice to write library code such that the compiler can help programmers avoid doing stupid things. And I know there are a lot of folks who can figure out cleverer type hackery than I can, so one can always hope (and maybe ask Oleg?)... (But if noone has an idea how to do this in an acceptable way, then I'm all for withFile.) -- David Roundy Dept. of Physics Oregon State University

Hello David, Thursday, October 26, 2006, 8:08:42 PM, you wrote:
In case I've been too vague, what I mean is that I'd like it if one could ensure that code such as
withFile "filename" ReadMode return >>= hGetContents
statically fails, rather than failing at runtime with a file handle closed
and how about passing file handle to another thread? ;) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Thu, Oct 26, 2006 at 08:16:47PM +0400, Bulat Ziganshin wrote:
Hello David,
Thursday, October 26, 2006, 8:08:42 PM, you wrote:
In case I've been too vague, what I mean is that I'd like it if one could ensure that code such as
withFile "filename" ReadMode return >>= hGetContents
statically fails, rather than failing at runtime with a file handle closed
and how about passing file handle to another thread? ;)
Good point. I wonder if it would make sense to (not now, but eventually, in an ideal haskell standard library) give IO a phantom type like ST has, which by default would refer to the thread involved, and then we could (at least optionally) open files with a thread-specific handle that can't be passed to another handle. Which could also be used to restrict withFile itself, something like withFile :: FilePath -> Mode -> (Handle t' -> IO t' ()) -> IO t () ? Not sure how that would work out with threads, but I'm sure it's possible... -- David Roundy Dept. of Physics Oregon State University

On Thu, Oct 26, 2006 at 09:08:42AM -0700, David Roundy wrote:
On Thu, Oct 26, 2006 at 01:15:11AM +0100, Ross Paterson wrote:
hunk ./System/IO.hs 369 +-- | @'withFile' name mode act@ opens a file using 'openFile' and passes +-- the resulting handle to the computation @act@. The handle will be +-- closed on exit from 'withFile', whether by normal termination or by +-- raising an exception. +withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r +withFile name mode = bracket (openFile name mode) hClose
I like this function (and use ones like it all the time in darcs), but do wonder whether it might be possible to ensure that the Handle doesn't escape, which would make it ultra-cool. I can't see how to do this, except to put the third argument into another monad and use a phantom type, which would be highly awkward, to say the least. But if there were a pretty approach, it would be very fancy.
In case I've been too vague, what I mean is that I'd like it if one could ensure that code such as
withFile "filename" ReadMode return >>= hGetContents
statically fails, rather than failing at runtime with a file handle closed exception. I know this is a stupid thing for the programmer to do, but it's nice to write library code such that the compiler can help programmers avoid doing stupid things. And I know there are a lot of folks who can figure out cleverer type hackery than I can, so one can always hope (and maybe ask Oleg?)...
He's already been there: http://www.haskell.org/pipermail/haskell/2006-January/017410.html

On Thu, Oct 26, 2006 at 06:15:59PM +0100, Ross Paterson wrote:
He's already been there:
http://www.haskell.org/pipermail/haskell/2006-January/017410.html
I yes, I saw that post, but didn't read it carefully, and didn't think of it, but am sure it must have been lurking in the back of my mind suggesting that this could be done. Usually I find Oleg's solutions well nigh incomprehensible, but in this case, it seems downright simple. The only catch is that you've got to use a new monad. And I suppose there's a possibility of confusing error messages. I suppose, though, that this kind of change would best be part of a complete refactoring of the IO monad (which is something I've been longing to do--to break (almost?) all the IO functions into classes, so you could write standard IO code that can run in other monads (e.g. a tarball-reading monad, or a quickcheck fake-IO monad, or in darcs the SlurpMonad), or could use it to statically enforce constraints (e.g. this bit of IO code doesn't touch the network, doesn't write to disk, etc). Not that I expect to have time to do this any time soon, but it'd be beautiful... and we all know that physicists (and I suppose computer scientists, too?) are suckers for the beautiful. -- David Roundy Dept. of Physics Oregon State University

On 10/26/06, David Roundy
In case I've been too vague, what I mean is that I'd like it if one could ensure that code such as
withFile "filename" ReadMode return >>= hGetContents
statically fails
That's what linear types (e.g. Clean's uniqueness types) are for. You
could use some kind of phantom type thing, but what if multiple files
are in use? It could get really ugly at the type level.
--
Taral
participants (6)
-
Bulat Ziganshin
-
David Roundy
-
Jason Dagit
-
Ross Paterson
-
Samuel Bronson
-
Taral