[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Why are byte ports "ports" as such?

This page is part of the web mail archives of SRFI 91 from before July 7th, 2015. The new archives for SRFI 91 contain all messages, not just those from before July 7th, 2015.

On 14-Apr-06, at 8:49 AM, John Cowan wrote:

Marc Feeley scripsit:

It is a pain to carry those two ports around in the code when the
program needs to communicate bidirectionally with some other entity
(another process, a user at a terminal, a socket, etc).  Moreover the
separation of a conceptually bidirectional channel into distinct
ports (input and output) destroys the conceptual link that they
have.  This hinders program understanding.  For example, with
bidirectional ports (close-port port) will close both sides of the
bidirectional port (i.e. the link between the input and output port
is preserved).  With two unidirectional ports you have to duplicate
some operations (closing ports, changing port settings, ...).

I find this rationale convincing (and think it should be added to the


  However, the socket API does permit closing input and output
sides of the socket separately, and there are use cases for this, so it
should be at least permitted though not the default.

For example, when you want to send an arbitrary-length undecorated
document to a server and retrieve an arbitrary-length undecorated document back, the simplest way to convey "end of document" is to close the output
side, while leaving the input side open in order to receive the reply.

That was the intent of the passage:

When an operation is said to apply to an input port it also applies to a bidirectional port. When an operation is said to apply to an output port
    it also applies to a bidirectional port.

but I guess it is not clear that this also applies to the port closing operations so I will add a note to that effect. So yes you can:

   (let ((tty (open-file "/dev/tty"))) ; bidirectional port
     (close-input-port tty)
     (close-output-port tty))

And similarly for any bidirectional port (presumably sockets when they are specified by another SRFI). For the record Gambit has:

     (list server-address: "www.apple.com"
           port-number: 80
           eol-encoding: 'cr-lf)))

A few unrelated editorial comments:

UTF-8 byte sequences of length 5 and 6 have been deprecated for a long,
long time.  They should not be referred to here.

This is an oversight. I'll change it to 1 to 4 bytes. That's what my reference implementation does anyway.

The SRFI should explicitly permit implementation-dependent encodings
and eol-encodings.  (XML 1.1 allows CR, LF, CR/LF, NEL=U+0085, and

What do you mean by "explicitly permit"? In general an implementation can extend an API any way it wishes! The spec is only a requirement.

The SRFI should depend only on the lighter-weight SRFI 66 (Octet vectors),
rather than on the heavier-weight SRFI 4.

It only depends on u8vectors which are common in SRFI 4 and SRFI 66. SRFI 66 has things that SRFI 4 does not have, and vice versa. I could add a reference to SRFI 66 though.

A warning is needed that non-default values of the create: file port
setting may be subject to race conditions on file systems that
don't provide full Posix semantics.

Sounds reasonable, as a warning.

Finally, this SRFI makes only trivial use of keyword objects, and IMHO
should be respecified to use symbols to reduce its dependencies.

I'll add something in the preamble saying:

The tokens of the form ``foo:'' used in this document will be called ``keywords''. On Scheme implementations supporting SRFI 88, these keywords correspond to the keyword objects specified in that SRFI. On Scheme implementations which do not
   support SRFI 88, these keywords are symbols.