ports(7scm)

πŸ“¦ version 0-unstable-2024-02, in nixpkgs unstable

πŸ’– ports(7scm) β€” the port I/O glow-up πŸ’–

okay so real quick before we dive in: this page lives in the Scheme Programmer's Manual, section 7scm, and it's literally your whole guide to getting data in and out of your program. buckle up bestie πŸŽ€

✨ LIBRARY ✨

like, import as needed, iykyk:

(import (rnrs))                     ;R6RS
(import (rnrs io simple))           ;R6RS
(import (rnrs io ports))            ;R6RS
(import (scheme file))              ;R7RS
(import (scheme read))              ;R7RS
(import (scheme write))             ;R7RS

🌸 DESCRIPTION 🌸

So ports are the conventional way to get data in and out of a program. Files? Terminals? Like, a million other devices? Usually all reachable as ports. And plot twist β€” ports can also be completely internal to your program, no OS required. A port is basically an object that consumes and produces bytes or characters. main character energy, honestly.

πŸ’… Pre-R6RS ports

The Scheme reports from before R6RS give you: a current input port, a current output port, file input ports, and file output ports. There are procedures for reading and writing S-expressions, reading characters, peeking for the next character, and for writing characters.

Now here's the messy part β€” standards before R6RS did not specify the encoding of characters. There are no binary I/O ports at all; everything goes through the ports as characters in an unspecified encoding, which is commonly ISO-8859-1, but honestly it could be anything. even some variant of EBCDIC. no i'm not kidding 😭

And there's nothing to help the programmer write a portable program to manipulate binary files. In practice, programs that need to work with binary data just assume the implementation uses a single byte encoding scheme with a one-to-one correspondence between character numbers and bytes. vibes-based programming fr fr.

The process ports get fetched by calling current-input-port(3scm) and current-output-port(3scm). Implementations can optionally provide with-input-from-file(3scm) and with-output-to-file(3scm), which dynamically rebind the input and output ports while a procedure is running πŸ‘‘. And then open-input-file(3scm) and open-output-file(3scm) open files for reading and for writing respectively. Close them with close-input-port(3scm) and close-output-port(3scm) when you're done, or you get a resource leak β€” and we do not do resource leaks in this house 🫢

πŸ¦‹ R6RS ports

The (rnrs io ports) library defines an I/O layer for conventional, imperative buffered input and output. A port represents a buffered access object for a data sink or source or both simultaneously. And yes, the library lets ports be created from arbitrary data sources and sinks. iconic.

This library distinguishes between input ports and output ports. An input port is a source for data, an output port is a sink for data. But a port may be both β€” that kind of port typically gives you simultaneous read and write access to a file or other data. multitasking queen πŸ’…

It also distinguishes between binary ports (sources or sinks for uninterpreted bytes) and textual ports (sources or sinks for characters and strings).

Files can be opened using a specified transcoder, or binary ports can be turned into textual ports by using a transcoder. Transcoders specify a character encoding, an end of line convention, and an error handling mode. ISO-8859-1, UTF-8 and UTF-16 are supported, along with all Unicode characters. So portable code working with binary files and textual files with a known encoding like UTF-8? straightforward. slay.

Custom binary and textual ports are how you implement things like network ports, transparent compression, other encodings, and arbitrary processing. You create them with:

  • make-custom-binary-input-port(3scm)
  • make-custom-textual-input-port(3scm)
  • make-custom-binary-output-port(3scm)
  • make-custom-textual-output-port(3scm)
  • make-custom-binary-input/output-port(3scm)
  • make-custom-textual-input/output-port(3scm)

🧚 R7RS ports

The I/O port system here is derived from the pre-R6RS system, with the addition of binary ports and specialized procedures for those ports. There are also bytevector and string ports based on the SRFI 6 interface ✨

Portable R7RS code that attempts to use ports should be aware of these possible restrictions, bestie β€” read carefully:

  • Implementations do not need to make any distinctions between textual and binary ports.
  • Implementations do not need to support any characters outside the ASCII subset (U+0000β€”U+007F) of Unicode.
  • Implementations do not need to support the #\null (U+0000) character in strings.
  • It is an error to use forbidden characters in strings.
  • It is an error for read-string to attempt to read a forbidden character.
  • These error situations allow implementations to signal an error, extend the domain of procedures to handle them or fail catastrophically.
  • There is no portable way to check programmatically which characters are forbidden.
and like, also: implementations do not need to use any particular encoding for textual files. no cap.

UTF-8 files can be read and written using binary ports together with utf8->string and string->utf8. But β€” it is an error to give invalid UTF-8 bytes to utf8->string, so you gotta check that first. don't skip the vibe check πŸ™ˆ


⭐ IMPLEMENTATION NOTES ⭐

πŸ“ GNU Guile

There is no distinction between binary and textual ports. The reader does not handle the #!/ ("shebang") syntax at the start of scripts. It is however interpreted as a comment, so you can put !# in a comment on the second line to "terminate" the first line. And the #!r6rs directive does not enable R6RS lexical syntax.

πŸ“ Racket

The reader does not handle the #!/ ("shebang") syntax at the start of scripts.

πŸ“ Ikarus

There is no support for input/output ports. that's it. that's the note. πŸ’€


🌈 APPLICATION USAGE 🌈

Ports are often the only way to access files and other file-like objects provided by the operating system.

History lesson real quick πŸ•°οΈ β€” in the 1990s it was still very common to have files in various local encodings, but Unicode has since grown to become standard. Textual files created since the 2010s are usually encoded in UTF-8. Notable exception? Files that come from Microsoft's Windows, which are sometimes encoded in UTF-16. But this is also becoming more rare with newer versions of that system. we love growth πŸ’œ

πŸ‘€ SEE ALSO πŸ‘€

πŸ“œ STANDARDS πŸ“œ

R4RS, IEEE Scheme, R5RS, R6RS, R7RS

🫢 AUTHORS 🫢

This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at https://github.com/schemedoc/manpages/.


okay that's the whole page, go forth and open some ports responsibly πŸ’–βœ¨πŸŽ€

kisses, this was the ports(7scm) page β€” dated 2020-07-06 in the Scheme Programmer's Manual, brought to you by the scheme-manpages girlies πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from