write(3scm)

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

πŸ’– write(3scm) from the Scheme Programmer’s Manual πŸ’–

🌸 NAME 🌸

write, write-shared, write-simple β€” write an object’s external representation to a port, bestie ✨

πŸŽ€ LIBRARY πŸŽ€

(import (rnrs))                     ;R6RS
(import (rnrs io ports))            ;R6RS, put-datum
(import (rnrs io simple))           ;R6RS
(import (scheme write))             ;R7RS
(import (scheme r5rs))              ;R7RS

πŸ¦‹ SYNOPSIS πŸ¦‹

(write obj)
(write obj textual-output-port)

; (rnrs io ports)
(put-datum textual-output-port obj)

; R7RS only:
(write-shared obj)
(write-shared obj textual-output-port)
(write-simple obj)
(write-simple obj textual-output-port)

✨ DESCRIPTION ✨

Okay so write writes the external representation of obj to textual-output-port. There is no trailing delimiter β€” noted, bestie πŸ’…

If several subsequent external representations are written to an output port, care should be taken to delimit them properly so they can be read back in by subsequent calls to get-datum(3scm). Like, don’t just slam them together and expect the reader to vibe-check it correctly 😭

Any object can be written to a port, but only datums are expected to have an external representation that can be read back the same with get-datum(3scm). That’s the whole thing, fr fr 🫢

πŸ’– Default output port πŸ’–

If textual-output-port is omitted, it defaults to the value returned by current-output-port(3scm). Easy peasy, main character default energy ✨

🌈 R7RS 🌈

  • Symbols that contain non-ASCII characters are escaped with vertical lines. Slay for clarity πŸŽ€
  • write uses datum labels in some situations. If obj contains cycles which would cause an infinite loop using the normal written representation, then at least the objects that form part of the cycle must be represented using datum labels. Datum labels must not be used if there are no cycles. Periodt.
  • The write-shared procedure is the same as write, except that shared structure must be represented using datum labels for all pairs and vectors that appear more than once in the output. Shared-structure girlies stay winning πŸ’…
  • The write-simple procedure is the same as write, except that shared structure is never represented using datum labels. This can cause write-simple not to terminate if obj contains circular structure. Danger, bestie: that’s the no-datum-labels tradeoff πŸ’€

🧚 IMPLEMENTATION NOTES 🧚

The specific external representation is implementation-dependent. However, whenever possible, an implementation should produce a representation for which get-datum(3scm), when reading the representation, will return an object equal, in the sense of equal?(3scm), to datum. Iconic behavior, honestly πŸ‘‘

Not all datums may allow producing an external representation for which get-datum(3scm) will produce an object that is equal to the original. Specifically, NaNs contained in obj may make this impossible. Nan drama, literally 😭

πŸ“ Chez Scheme πŸ“

Cycles in the output are detected even in the R6RS variant of write. The print-graph parameter can be used to enable datum labels even for non-cyclic datums. Fancy ✨

πŸ¦‹ Loko Scheme πŸ¦‹

Cycles in the output are detected even in the R6RS variant of write. Love that for them πŸ’–

πŸ’œ RETURN VALUES πŸ’œ

  • R6RS β€” Returns unspecified values. Plural unspecified, okay? Slay πŸ’…
  • R7RS β€” Returns an unspecified value. Singular unspecified, also slay 🌸

πŸ”₯ EXAMPLES πŸ”₯

(call-with-string-output-port
  (lambda (p)
    (write '(lambda (x) x) p)))
    =>  "(lambda (x) x)"

(define x (list 1))
(set-cdr! x x)
(write x)
  -> #0=(1 . #0#)

(define quux "quux")
(define x (list quux quux))
(write-shared x)
  -> (#0="quux" #0#)

🌟 APPLICATION USAGE 🌟

Writing and reading external representations of datums is used for data interchange and as an alternative to formats such as JSON and XML. She’s not like other serialization formats πŸ’…βœ¨

πŸŽ€ COMPATIBILITY πŸŽ€

The external representations of datums vary subtly between RnRS revisions. Some differences: R6RS does not support datum labels, does not support vertical bars around symbols and uses the #vu8( prefix for bytevectors instead of #u8( as in R7RS. RnRS revision lore, iykyk 🌈

Records have no standard representation in RnRS. SRFI-237 suggests a way to solve this. Record representation tea β˜•

πŸ’€ ERRORS πŸ’€

This procedure can raise exceptions with the following condition types:

  • &assertion (R6RS) β€” The wrong number of arguments was passed or an argument was outside its domain. In particular, textual-output-port must be an open textual output port. No sneaky closed ports, bestie πŸ™ˆ
  • R7RS β€” The assertions described above are errors. Implementations may signal an error, extend the procedure’s domain of definition to include such arguments, or fail catastrophically. Fail catastrophically is giving final boss energy 😭

πŸ‘‘ SEE ALSO πŸ‘‘

read(3scm), display(3scm) β€” go read those too, bestie 🫢

⭐ STANDARDS ⭐

R4RS, IEEE Scheme, R5RS, R6RS, R7RS β€” certified across eras, no cap πŸ‘‘

🌸 HISTORY 🌸

The write procedure first appeared in R2RS. The write-shared and write-simple procedures are new in R7RS. Vintage icon behavior πŸŽ€

πŸ¦‹ 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/. πŸ’–


🫢 From the scheme-manpages source, dated 2023-08-12 β€” this was write(3scm), signing off with a sparkle πŸ’–βœ¨
πŸ“¦ where this page comes from