Re: [Haskell-cafe] Coming up with a better API for Network.Socket.recv

2009-02-27 Thread Johan Tibell
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

2009-02-26 Thread Brandon S. Allbery KF8NH

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

2009-02-26 Thread Bryan O'Sullivan
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

2009-02-26 Thread Jonathan Cast
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

2009-02-26 Thread Johan Tibell
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