Re: [Haskell-cafe] Coming up with a better API for Network.Socket.recv
On Fri, Feb 27, 2009 at 12:03 AM, Bryan O'Sullivan wrote: > On Thu, Feb 26, 2009 at 1:45 PM, Johan Tibell > wrote: >> >> I find it quite inconvenient to use the `recv` function in >> Network.Socket as it throws an exception when reaching EOF and there's >> no way to check whether EOF has been reached before calling `recv`. > > I agree, the current behaviour is quite unfortunate. In fact, I'm pretty > sure I added an entry point named recv_ to network-bytestring to work around > precisely this problem. Yes, that's indeed the reason we added it. My current thinking is that we'd drop `recv` from network-bytestring in favor of `recv_`. I've checked how many libraries on Hackage depend on network-bytestring and there are few enough that we could make such a change. It's a bit unfortunate that these libraries have an open dependency on network-bytestring (e.g. network-bytestring >= 0.1.1.2). I will contact the maintainers of those libraries before making a new release. > There's another problem with the network APIs: they mirror the BSD socket > API too faithfully, and provide insufficient type safety. You can try to > send on an unconnected socket, and to bind a socket that's already > connected, both of which should be statically forbidden. The APIs for > datagram-oriented networking ought to be distinct from the stream-oriented > variety, I think, even if the underlying C-level calls end up being > substantially the same. > > Really, the big thing that's missing here is enough application of elbow > grease from someone who's got a good eye for design and doesn't mind all the > slog involved. I think that if someone published a network-alt package (much > like the one that was published a few years ago) and tooted their horn > vigorously enough, we could put the existing network package out to pasture > in fairly short order. I would be interested in trying to create a better API. However, I'm not sure what it would look like. The design space is pretty big. * How can we provide the static guarantees we want? Perhaps with some kind of lightweight monadic regions but if so which definition should we use i.e. can a region return a Socket to the parent region or not? This has implications on how easy the API is to understand. * Should we use enumerators or not? Can they be added as a convenience layer on top of type safe low-level layer? Cheers, Johan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Coming up with a better API for Network.Socket.recv
On 2009 Feb 26, at 16:45, Johan Tibell wrote: definition of `recv` would look like. My current thinking is that it would mimic what C/Python/Java does and return a zero length ByteString when EOF is reached. Ew. Isn't this what Maybe is for? Anyway, the reason recv doesn't return 0 is that if you have a datagram socket, a zero-length recv is valid and doesn't mean EOF. (Not that many UDP-using programs know what to do with a 0-length packet.) So you need to indicate "EOF" (sender closed its end) in some different way. It *should* have been Maybe -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH PGP.sig Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Coming up with a better API for Network.Socket.recv
On Thu, Feb 26, 2009 at 1:45 PM, Johan Tibell wrote: > I find it quite inconvenient to use the `recv` function in > Network.Socket as it throws an exception when reaching EOF and there's > no way to check whether EOF has been reached before calling `recv`. I agree, the current behaviour is quite unfortunate. In fact, I'm pretty sure I added an entry point named recv_ to network-bytestring to work around precisely this problem. > I'm also interested in understanding the reasons behind the design of > the `recv` function in the network library. I think that it was modeled after the Handle API, which provides an isEOF function that you can call to see whether a Handle is done before you try reading it. This works well enough on a Handle because it's buffered, but sockets aren't buffered, and the symmetric isEOF function isn't available. I don't like the way the Handle API works, but I grudgingly accept it as not amenable to change. There's another problem with the network APIs: they mirror the BSD socket API too faithfully, and provide insufficient type safety. You can try to send on an unconnected socket, and to bind a socket that's already connected, both of which should be statically forbidden. The APIs for datagram-oriented networking ought to be distinct from the stream-oriented variety, I think, even if the underlying C-level calls end up being substantially the same. Really, the big thing that's missing here is enough application of elbow grease from someone who's got a good eye for design and doesn't mind all the slog involved. I think that if someone published a network-alt package (much like the one that was published a few years ago) and tooted their horn vigorously enough, we could put the existing network package out to pasture in fairly short order. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Coming up with a better API for Network.Socket.recv
On Thu, 2009-02-26 at 22:45 +0100, Johan Tibell wrote: > Hi all, > > I find it quite inconvenient to use the `recv` function in > Network.Socket as it throws an exception when reaching EOF and there's > no way to check whether EOF has been reached before calling `recv`. > This means that all calls to `recv` needs to be wrapped in an > exception handler. NB: tryJust (guard . isEOFError) $ recv ... with base-4 or tryJust (ioErrors >=> guard . isEOFError) $ recv ... with base-3, right? > I've been thinking about changing the version of > `recv` that's included in the network-bytestring library [1] so it > behaves differently from the one in the network library. Before I do > so I thought I should see if we can reach a consensus on what a nicer > definition of `recv` would look like. My current thinking is that it > would mimic what C/Python/Java does and return a zero length > ByteString when EOF is reached. +1 In the interest of totality. Also, Prelude.getChar/System.IO.hGetChar should have return type IO (Maybe Char) in the interest of totality. > I'm also interested in understanding the reasons behind the design of > the `recv` function in the network library. More generally, I'm > interested in discussing the pros and cons of the current Haskell I/O > library design where the different read functions throw EOF exceptions > and you have to call e.g. hIsEOF before reading from a Handle. > > 1. http://github.com/tibbe/network-bytestring jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Coming up with a better API for Network.Socket.recv
Hi all, I find it quite inconvenient to use the `recv` function in Network.Socket as it throws an exception when reaching EOF and there's no way to check whether EOF has been reached before calling `recv`. This means that all calls to `recv` needs to be wrapped in an exception handler. I've been thinking about changing the version of `recv` that's included in the network-bytestring library [1] so it behaves differently from the one in the network library. Before I do so I thought I should see if we can reach a consensus on what a nicer definition of `recv` would look like. My current thinking is that it would mimic what C/Python/Java does and return a zero length ByteString when EOF is reached. I'm also interested in understanding the reasons behind the design of the `recv` function in the network library. More generally, I'm interested in discussing the pros and cons of the current Haskell I/O library design where the different read functions throw EOF exceptions and you have to call e.g. hIsEOF before reading from a Handle. 1. http://github.com/tibbe/network-bytestring Cheers, Johan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe