This subsection is based on the specification of SRFI-38 written by Ray Dillinger.
This SRFI creates an alternative external representation for data
written and read using
read-with-shared-structure. It is identical to the grammar for
external representation for data written and read with
read given in section 7 of R5RS, except that the single
<datum> --> <simple datum> | <compound datum>
is replaced by the following five productions:
<datum> --> <defining datum> | <nondefining datum> | <defined datum> <defining datum> --> #<indexnum>=<nondefining datum> <defined datum> --> #<indexnum># <nondefining datum> --> <simple datum> | <compound datum> <indexnum> --> <digit 10>+
Writes an external representation of obj to the given port.
Strings that appear in the written representation are enclosed in
doublequotes, and within those strings backslash and doublequote
characters are escaped by backslashes. Character objects are written
Objects which denote locations rather than values (cons cells, vectors,
and non-zero-length strings in R5RS scheme; also Guile’s structs,
bytevectors and ports and hash-tables), if they appear at more than one
point in the data being written, are preceded by ‘#N=’ the
first time they are written and replaced by ‘#N#’ all
subsequent times they are written, where N is a natural number
used to identify that particular object. If objects which denote
locations occur only once in the structure, then
write-with-shared-structure must produce the same external
representation for those objects as
write-with-shared-structure terminates in finite time and
produces a finite representation when writing finite data.
write-with-shared-structure returns an unspecified value. The
port argument may be omitted, in which case it defaults to the
value returned by
(current-output-port). The optarg
argument may also be omitted. If present, its effects on the output and
return value are unspecified but
still write a representation that can be read by
read-with-shared-structure. Some implementations may wish to use
optarg to specify formatting conventions, numeric radixes, or
return values. Guile’s implementation ignores optarg.
For example, the code
(begin (define a (cons 'val1 'val2)) (set-cdr! a a) (write-with-shared-structure a))
should produce the output
#1=(val1 . #1#). This shows a cons
cdr contains itself.
read-with-shared-structure converts the external representations
of Scheme objects produced by
Scheme objects. That is, it is a parser for the nonterminal
‘<datum>’ in the augmented external representation grammar defined
read-with-shared-structure returns the next object
parsable from the given input port, updating port to point to the
first character past the end of the external representation of the
If an end-of-file is encountered in the input before any characters are
found that can begin an object, then an end-of-file object is returned.
The port remains open, and further attempts to read it (by
read will also return an
end-of-file object. If an end of file is encountered after the
beginning of an object’s external representation, but the external
representation is incomplete and therefore not parsable, an error is
The port argument may be omitted, in which case it defaults to the
value returned by
(current-input-port). It is an error to read
from a closed port.