6.12.11 Venerable Port Interfaces

Over the 25 years or so that Guile has been around, its port system has evolved, adding many useful features. At the same time there have been four major Scheme standards released in those 25 years, which also evolve the common Scheme understanding of what a port interface should be. Alas, it would be too much to ask for all of these evolutionary branches to be consistent. Some of Guile’s original interfaces don’t mesh with the later Scheme standards, and yet Guile can’t just drop old interfaces. Sadly as well, the R6RS and R7RS standards both part from a base of R5RS, but end up in different and somewhat incompatible designs.

Guile’s approach is to pick a set of port primitives that make sense together. We document that set of primitives, design our internal interfaces around them, and recommend them to users. As the R6RS I/O system is the most capable standard that Scheme has yet produced in this domain, we mostly recommend that; (ice-9 binary-ports) and (ice-9 textual-ports) are wholly modelled on (rnrs io ports). Guile does not wholly copy R6RS, however; See Incompatibilities with the R6RS.

At the same time, we have many venerable port interfaces, lore handed down to us from our hacker ancestors. Most of these interfaces even predate the expectation that Scheme should have modules, so they are present in the default environment. In Guile we support them as well and we have no plans to remove them, but again we don’t recommend them for new users.

Scheme Procedure: char-ready? [port]

Return #t if a character is ready on input port and return #f otherwise. If char-ready? returns #t then the next read-char operation on port is guaranteed not to hang. If port is a file port at end of file then char-ready? returns #t.

char-ready? exists to make it possible for a program to accept characters from interactive ports without getting stuck waiting for input. Any input editors associated with such ports must make sure that characters whose existence has been asserted by char-ready? cannot be rubbed out. If char-ready? were to return #f at end of file, a port at end of file would be indistinguishable from an interactive port that has no ready characters.

Note that char-ready? only works reliably for terminals and sockets with one-byte encodings. Under the hood it will return #t if the port has any input buffered, or if the file descriptor that backs the port polls as readable, indicating that Guile can fetch more bytes from the kernel. However being able to fetch one byte doesn’t mean that a full character is available; See Encoding. Also, on many systems it’s possible for a file descriptor to poll as readable, but then block when it comes time to read bytes. Note also that on Linux kernels, all file ports backed by files always poll as readable. For non-file ports, this procedure always returns #t, except for soft ports, which have a char-ready? handler. See Soft Ports.

In short, this is a legacy procedure whose semantics are hard to provide. However it is a useful check to see if any input is buffered. See Non-Blocking I/O.

Scheme Procedure: read-char [port]

The same as get-char, except that port defaults to the current input port. See Textual I/O.

Scheme Procedure: peek-char [port]

The same as lookahead-char, except that port defaults to the current input port. See Textual I/O.

Scheme Procedure: unread-char cobj [port]

The same as unget-char, except that port defaults to the current input port, and the arguments are swapped. See Textual I/O.

Scheme Procedure: unread-string str port
C Function: scm_unread_string (str, port)

The same as unget-string, except that port defaults to the current input port, and the arguments are swapped. See Textual I/O.

Scheme Procedure: newline [port]

Send a newline to port. If port is omitted, send to the current output port. Equivalent to (put-char port #\newline).

Scheme Procedure: write-char chr [port]

The same as put-char, except that port defaults to the current input port, and the arguments are swapped. See Textual I/O.