
An extflonum is like a flonum, but with 80-bit precision and not a number in the sense of `number?': only operations such as `extfl+' work on extflonums, and only on platforms where extflonums can be implemented by hardware without interefering with flonums (i.e., on platforms where SSE instructions are used for double-precision floats). [Patch provided by Michael Filonenko and revised by Matthew.] The compiler tracks information about bindings that are known to hold extflonums, but the JIT does not yet exploit this information to unbox them (except as intermediate results).
582 lines
28 KiB
Racket
582 lines
28 KiB
Racket
#lang scribble/doc
|
|
@(require scribble/bnf "mz.rkt")
|
|
|
|
@title[#:tag "printing" #:style 'quiet]{The Printer}
|
|
|
|
The Racket printer supports three modes:
|
|
|
|
@itemlist[
|
|
|
|
@item{@racket[write] mode prints core datatypes in such a way that
|
|
using @racket[read] on the output produces a value that is
|
|
@racket[equal?] to the printed value;}
|
|
|
|
@item{@racket[display] mode prints core datatypes in a more
|
|
``end-user'' style rather than ``programmer'' style; for
|
|
example, a string @racket[display]s as its content characters
|
|
without surrounding @litchar{"}s or escapes;}
|
|
|
|
@item{@racket[print] mode by default---when
|
|
@racket[print-as-expression] is @racket[#t]---prints most
|
|
datatypes in such a way that evaluating the output as an
|
|
expression produces a value that is @racket[equal?] to the
|
|
printed value; when @racket[print-as-expression] is set to
|
|
@racket[#f], then @racket[print] mode is like @racket[write]
|
|
mode.}
|
|
|
|
]
|
|
|
|
In @racket[print] mode when @racket[print-as-expression] is
|
|
@racket[#t] (as is the default), a value prints at a @deftech{quoting
|
|
depth} of either @racket[0] (unquoted) or @racket[1] (quoted). The
|
|
initial quoting depth is accepted as an optional argument by
|
|
@racket[print], and printing of some compound datatypes adjusts the
|
|
print depth for component values. For example, when a list is printed
|
|
at quoting depth @racket[0] and all of its elements are
|
|
@deftech{quotable}, the list is printed with a @litchar{'} prefix, and
|
|
the list's elements are printed at quoting depth @racket[1].
|
|
|
|
When the @racket[print-graph] parameter is set to @racket[#t], then
|
|
the printer first scans an object to detect cycles. The scan traverses
|
|
the components of pairs, mutable pairs, vectors, boxes (when
|
|
@racket[print-box] is @racket[#t]), hash tables (when
|
|
@racket[print-hash-table] is @racket[#t]), fields of structures
|
|
exposed by @racket[struct->vector] (when @racket[print-struct] is
|
|
@racket[#t]), and fields of structures exposed by printing when the
|
|
structure's type has the @racket[prop:custom-write] property. If
|
|
@racket[print-graph] is @racket[#t], then this information is used to
|
|
print sharing through graph definitions and references (see
|
|
@secref["parse-graph"]). If a cycle is detected in the initial scan,
|
|
then @racket[print-graph] is effectively set to @racket[#t]
|
|
automatically.
|
|
|
|
With the exception of displaying @tech{byte strings}, printing is defined in
|
|
terms of Unicode characters; see @secref["ports"] for information
|
|
on how a character stream is written to a port's underlying byte
|
|
stream.
|
|
|
|
|
|
@section[#:tag "print-symbol"]{Printing Symbols}
|
|
|
|
@tech{Symbols} containing spaces or special characters @racket[write] using
|
|
escaping @litchar{\} and quoting @litchar{|}s. When the
|
|
@racket[read-case-sensitive] parameter is set to @racket[#f], then
|
|
symbols containing uppercase characters also use escaping
|
|
@litchar{\} and quoting @litchar{|}s. In addition, symbols are
|
|
quoted with @litchar{|}s or leading @litchar{\} when they would
|
|
otherwise print the same as a numerical constant or as a delimited
|
|
@litchar{.} (when @racket[read-accept-dot] is @racket[#t]).
|
|
|
|
When @racket[read-accept-bar-quote] is @racket[#t], @litchar{|}s are
|
|
used in printing when one @litchar{|} at the beginning and one
|
|
@litchar{|} at the end suffice to correctly print the
|
|
symbol. Otherwise, @litchar{\}s are always used to escape special
|
|
characters, instead of quoting them with @litchar{|}s.
|
|
|
|
When @racket[read-accept-bar-quote] is @racket[#f], then @litchar{|}
|
|
is not treated as a special character. The following are always
|
|
special characters:
|
|
|
|
@t{
|
|
@hspace[2] @litchar{(} @litchar{)} @litchar{[} @litchar{]}
|
|
@litchar["}"] @litchar["}"]
|
|
@litchar{"} @litchar{,} @litchar{'} @litchar{`}
|
|
@litchar{;} @litchar{\}
|
|
}
|
|
|
|
In addition, @litchar{#} is a special character when it appears at the
|
|
beginning of the symbol, and when it is not followed by @litchar{%}.
|
|
|
|
Symbols @racket[display] without escaping or quoting special
|
|
characters. That is, the display form of a symbol is the same as the
|
|
display form of @racket[symbol->string] applied to the symbol.
|
|
|
|
Symbols @racket[print] the same as they @racket[write], unless
|
|
@racket[print-as-expression] is set to @racket[#t] (as is the default) and the current
|
|
@tech{quoting depth} is @racket[0]. In that case, the symbol's
|
|
@racket[print]ed form is prefixed with @litchar{'}. For the purposes
|
|
of printing enclosing datatypes, a symbol is @tech{quotable}.
|
|
|
|
@section[#:tag "print-number"]{Printing Numbers}
|
|
|
|
A @tech{number} prints the same way in @racket[write], @racket[display], and
|
|
@racket[print] modes. For the purposes of printing enclosing
|
|
datatypes, a number is @tech{quotable}.
|
|
|
|
A @tech{complex number} that is not a @tech{real number} always prints
|
|
as @nonterm{m}@litchar{+}@nonterm{n}@litchar{i}, where @nonterm{m} and
|
|
@nonterm{n} are the printed forms of its real and imaginary parts,
|
|
respectively.
|
|
|
|
An inexact real number prints with either a @litchar{.} decimal
|
|
point, an @litchar{e} exponent marker, or both. The form is selected
|
|
so that the output is as short as possible, with the constraint that
|
|
reading the printed form back in produces an @racket[equal?] number.
|
|
|
|
An exact @racket[0] prints as @litchar{0}.
|
|
|
|
A positive, exact integer prints as a sequence of decimal digits that
|
|
does not start with @racket[0].
|
|
|
|
A positive, exact, real, non-integer number prints as
|
|
@nonterm{m}@litchar{/}@nonterm{n}, where @nonterm{m} and @nonterm{n}
|
|
are the printed forms of the number's numerator and denominator (as
|
|
determined by @racket[numerator] and @racket[denominator]).
|
|
|
|
A negative @tech{exact number} prints with a @litchar{-} prefix on the
|
|
printed form of the number's exact negation.
|
|
|
|
@section[#:tag "print-extflonum"]{Printing Extflonums}
|
|
|
|
An @tech{extflonum} prints the same way in @racket[write],
|
|
@racket[display], and @racket[print] modes. For the purposes of
|
|
printing enclosing datatypes, an extflonum is @tech{quotable}.
|
|
|
|
An extflonum prints in the same way an inexact number, but
|
|
always with a @litchar{t} or @litchar{T} exponent marker. When
|
|
extflonum operations are supported, printing always uses
|
|
@litchar{t}; when extflonum operations are not supported, an
|
|
extflonum prints the same as its reader (see @secref["reader"])
|
|
source, since reading is the only way to produce an extflonum.
|
|
|
|
@section[#:tag "print-booleans"]{Printing Booleans}
|
|
|
|
The @tech{boolean} constant @racket[#t] prints as @litchar{#true} or @litchar{#t} in
|
|
all modes (@racket[display], @racket[write], and @racket[print]),
|
|
depending on the value of @racket[print-boolean-long-form], and the
|
|
constant @racket[#f] prints as @litchar{#false} or @litchar{#f}. For
|
|
the purposes of printing enclosing datatypes, a symbol is
|
|
@tech{quotable}.
|
|
|
|
@section[#:tag "print-pairs"]{Printing Pairs and Lists}
|
|
|
|
In @racket[write] and @racket[display] modes, an empty @tech{list} prints as
|
|
@litchar{()}. A @tech{pair} normally prints starting with @litchar{(}
|
|
followed by the printed form of its @racket[car]. The rest of the
|
|
printed form depends on the @racket[cdr]:
|
|
|
|
@itemize[
|
|
|
|
@item{If the @racket[cdr] is a pair or the empty list, then the
|
|
printed form of the pair completes with the printed form of the
|
|
@racket[cdr], except that the leading @litchar{(} in the
|
|
@racket[cdr]'s printed form is omitted.}
|
|
|
|
@item{Otherwise, the printed for of the pair continues with a space,
|
|
@litchar{.}, another space, the printed form of the
|
|
@racket[cdr], and a @litchar{)}.}
|
|
|
|
]
|
|
|
|
If @racket[print-reader-abbreviations] is set to @racket[#t], then
|
|
pair printing in @racket[write] mode is adjusted in the case of a pair
|
|
that starts a two-element list whose first element is @racket['quote],
|
|
@racket['quasiquote], @racket['unquote], @racket['unquote-splicing],
|
|
@racket['syntax], @racket['quasisyntax], @racket['unsyntax], or
|
|
@racket['unsyntax-splicing]. In that case, the pair is printed with
|
|
the corresponding reader syntax: @litchar{'}, @litchar{`},
|
|
@litchar{,}, @litchar[",@"], @litchar{#'}, @litchar{#`}, @litchar{#,},
|
|
or @litchar["#,@"], respectively. After the reader syntax, the second
|
|
element of the list is printed. When the list is a tail of an
|
|
enclosing list, the tail is printed after a @litchar{.} in the
|
|
enclosing list (after which the reader abbreviations work), instead of
|
|
including the tail as two elements of the enclosing list.
|
|
|
|
The printed form of a pair is the same in both @racket[write] and
|
|
@racket[display] modes, except as the printed form of the pair's
|
|
@racket[car] and @racket[cdr] vary with the mode. The @racket[print]
|
|
form is also the same if @racket[print-as-expression] is @racket[#f]
|
|
or the quoting depth is @racket[1].
|
|
|
|
For @racket[print] mode when @racket[print-as-expression] is
|
|
@racket[#t] and the @tech{quoting depth} is @racket[0], then the empty
|
|
list prints as @litchar{'()}. For a pair whose @racket[car] and
|
|
@racket[cdr] are @tech{quotable}, the pair prints in @racket[write]
|
|
mode but with a @litchar{'} prefix; the pair's content is printed with
|
|
@tech{quoting depth} @racket[1]. Otherwise, when the @racket[car] or
|
|
@racket[cdr] is not @tech{quotable}, then pair prints with either
|
|
@litchar{cons} (when the @racket[cdr] is not a pair), @litchar{list}
|
|
(when the pair is a list), or @litchar{list*} (otherwise) after the
|
|
opening @litchar{(}, any @litchar{.} that would otherwise be printed
|
|
is suppressed, and the pair content is printed at @tech{quoting depth}
|
|
@racket[0]. In all cases, when @racket[print-as-expression] is
|
|
@racket[#t] for @racket[print] mode, then the value of
|
|
@racket[print-reader-abbreviations] is ignored and reader
|
|
abbreviations are always used for lists printed at @tech{quoting
|
|
depth} @racket[1].
|
|
|
|
By default, mutable pairs (as created with @racket[mcons]) print the
|
|
same as pairs for @racket[write] and @racket[display], except that
|
|
@litchar["{"] and @litchar["}"] are used instead of @litchar{(} and
|
|
@litchar{)}. Note that the reader treats @litchar["{"]...@litchar["}"]
|
|
and @litchar{(}...@litchar{)} equivalently on input, creating
|
|
immutable pairs in both cases. Mutable pairs in @racket[print] mode with
|
|
@racket[print-as-expression] as @racket[#f] or a @tech{quoting depth}
|
|
of @racket[1] also use @litchar["{"] and @litchar["}"]. In
|
|
@racket[print] mode with @racket[print-as-expression] as @racket[#t]
|
|
and a @tech{quoting depth} of @racket[0], a mutable pair prints as
|
|
@litchar{(mcons }, the @racket[mcar] and @racket[mcdr] printed at
|
|
@tech{quoting depth} @racket[0] and separated by a space, and a
|
|
closing @litchar{)}.
|
|
|
|
If the @racket[print-pair-curly-braces] parameter is set to
|
|
@racket[#t], then pairs print using @litchar["{"] and @litchar["}"]
|
|
when not using @racket[print] mode with @racket[print-as-expression] as
|
|
@racket[#t] and a @tech{quoting depth} of @racket[0]. If the
|
|
@racket[print-mpair-curly-braces] parameter is set to @racket[#f],
|
|
then mutable pairs print using @litchar{(} and @litchar{)} in that
|
|
mode.
|
|
|
|
For the purposes of printing enclosing datatypes, an empty list is
|
|
always @tech{quotable}, a pair is @tech{quotable} when its
|
|
@racket[car] and @racket[cdr] are @tech{quotable}, and a mutable list
|
|
is never @tech{quotable}.
|
|
|
|
@section[#:tag "print-string"]{Printing Strings}
|
|
|
|
All @tech{strings} @racket[display] as their literal character sequences.
|
|
|
|
The @racket[write] or @racket[print] form of a string starts with @litchar{"} and ends
|
|
with another @litchar{"}. Between the @litchar{"}s, each character is
|
|
represented. Each graphic or blank character is represented as itself,
|
|
with two exceptions: @litchar{"} is printed as @litchar{\"}, and
|
|
@litchar{\} is printed as @litchar{\\}. Each non-graphic, non-blank
|
|
character (according to @racket[char-graphic?] and
|
|
@racket[char-blank?]) is printed using the escape sequences described
|
|
in @secref["parse-string"], using @litchar{\a}, @litchar{\b},
|
|
@litchar{\t}, @litchar{\n}, @litchar{\v}, @litchar{\f}, @litchar{\r},
|
|
or @litchar{\e} if possible, otherwise using @litchar{\u} with four
|
|
hexadecimal digits or @litchar{\U} with eight hexadecimal digits
|
|
(using the latter only if the character value does not fit into four
|
|
digits).
|
|
|
|
All byte strings @racket[display] as their literal byte sequence; this
|
|
byte sequence may not be a valid UTF-8 encoding, so it may not
|
|
correspond to a sequence of characters.
|
|
|
|
The @racket[write] or @racket[print] form of a byte string starts with @litchar{#"} and
|
|
ends with a @litchar{"}. Between the @litchar{"}s, each byte is
|
|
written using the corresponding ASCII decoding if the byte is between
|
|
0 and 127 and the character is graphic or blank (according to
|
|
@racket[char-graphic?] and @racket[char-blank?]). Otherwise, the byte
|
|
is written using @litchar{\a}, @litchar{\b}, @litchar{\t},
|
|
@litchar{\n}, @litchar{\v}, @litchar{\f}, @litchar{\r}, or
|
|
@litchar{\e} if possible, otherwise using @litchar{\} followed by one
|
|
to three octal digits (only as many as necessary).
|
|
|
|
For the purposes of printing enclosing datatypes, a string or a byte
|
|
string is @tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-vectors"]{Printing Vectors}
|
|
|
|
In @racket[display] mode, the printed form of a @tech{vector} is @litchar{#}
|
|
followed by the printed form of @racket[vector->list] applied to the
|
|
vector. In @racket[write] mode, the printed form is the same, except
|
|
that when the @racket[print-vector-length] parameter is @racket[#t], a
|
|
decimal integer is printed after the @litchar{#}, and a repeated last
|
|
element is printed only once.
|
|
|
|
Vectors @racket[print] the same as they @racket[write], unless
|
|
@racket[print-as-expression] is set to @racket[#t] and the current
|
|
@tech{quoting depth} is @racket[0]. In that case, if all of the
|
|
vector's elements are @tech{quotable}, then the vector's
|
|
@racket[print]ed form is prefixed with @litchar{'} and its elements
|
|
printed with @tech{quoting depth} @racket[1]. If its elements are not
|
|
all @tech{quotable}, then the vector @racket[print]s as
|
|
@litchar["(vector "], the elements at @tech{quoting depth} @racket[0],
|
|
and a closing @litchar{)}. A vector is @tech{quotable} when all of
|
|
its elements are @tech{quotable}.
|
|
|
|
In @racket[write] or @racket[display] mode, an @tech{flvector} prints
|
|
like a @tech{vector}, but with a @litchar{#fl} prefix instead of
|
|
@litchar{#}. A @tech{fxvector} similarly prints with a @litchar{#fx}
|
|
prefix instead of @litchar{#}. The @racket[print-vector-length]
|
|
parameter affects @tech{flvector} and @tech{fxvector} printing the
|
|
same as @tech{vector} printing. In @racket[print] mode,
|
|
@tech{flvectors} and @tech{fxvectors} are not @tech{quotable}, and
|
|
they print like a @tech{vector} at @tech{quoting depth} 0 using a
|
|
@litchar["(flvector "] or @litchar["(fxvector "] prefix, respectively.
|
|
|
|
|
|
@section[#:tag "print-structure"]{Printing Structures}
|
|
|
|
When the @racket[print-struct] parameter is set to @racket[#t], then
|
|
the way that @tech{structures} print depends on details of the structure type
|
|
for which the structure is an instance:
|
|
|
|
@itemize[
|
|
|
|
@item{If the structure type is a @tech{prefab} structure type,
|
|
then it prints in @racket[write] or @racket[display] mode using
|
|
@litchar{#s(} followed by the @tech{prefab} structure type key,
|
|
then the printed form of each field in the structure, and then
|
|
@litchar{)}.
|
|
|
|
In @racket[print] mode when @racket[print-as-expression] is set
|
|
to @racket[#t] and the current @tech{quoting depth} is
|
|
@racket[0], if the structure's content is all @tech{quotable},
|
|
then the structure's @racket[print]ed form is prefixed with
|
|
@litchar{'} and its content is printed with @tech{quoting
|
|
depth} @racket[1]. If any of its content is not quotable, then
|
|
the structure type prints the same as a non-@tech{prefab}
|
|
structure type.
|
|
|
|
An instance of a @tech{prefab} structure type is @tech{quotable}
|
|
when all of its content is @tech{quotable}.}
|
|
|
|
@item{If the structure has a @racket[prop:custom-write] property
|
|
value, then the associated procedure is used to print the
|
|
structure, unless the @racket[print-unreadable] parameter is
|
|
set to @racket[#f].
|
|
|
|
For @racket[print] mode, an instance of a structure type with a
|
|
@racket[prop:custom-write] property is treated as
|
|
@tech{quotable} if it has the
|
|
@racket[prop:custom-print-quotable] property with a value of
|
|
@racket['always]. If it has @racket['maybe] as the property
|
|
value, then the structure is treated as @tech{quotable} if its
|
|
content is @tech{quotable}, where the content is determined by
|
|
the values recursively printed by the structure's
|
|
@racket[prop:custom-write] procedure. Finally, if the structure
|
|
has @racket['self] as the property value, then it is treated as
|
|
@tech{quotable}.
|
|
|
|
In @racket[print] mode when @racket[print-as-expression] is
|
|
@racket[#t], the structure's @racket[prop:custom-write]
|
|
procedure is called with either @racket[0] or @racket[1] as the
|
|
@tech{quoting depth}, normally depending on the structure's
|
|
@racket[prop:custom-print-quotable] property value. If the
|
|
property value is @racket['always], the @tech{quoting depth} is
|
|
normally @racket[1]. If the property value is @racket['maybe],
|
|
then the @tech{quoting depth} is @racket[1] if the structure is
|
|
@tech{quotable}, or normally @racket[0] otherwise. If the
|
|
property value is @racket['self], then the quoting depth may be
|
|
@racket[0] or @racket[1]; it is normally @racket[0] if the
|
|
structure is not printed as a part of an enclosing
|
|
@tech{quotable} value, even though the structure is treated as
|
|
@tech{quotable}. Finally, if the property value is
|
|
@racket['never], then the @tech{quoting depth} is normally
|
|
@racket[0]. The @tech{quoting depth} can vary from its normal
|
|
value if the structure is printed with an explicit quoting
|
|
depth of @racket[1].}
|
|
|
|
@item{If the structure's type is transparent or if any ancestor is
|
|
transparent (i.e., @racket[struct?] on the instance produces
|
|
@racket[#t]), then the structure prints as the vector produced
|
|
by @racket[struct->vector] in @racket[display] mode, in
|
|
@racket[write] mode, or in @racket[print] mode when
|
|
@racket[print-as-expression] is set to @racket[#f] or when the
|
|
@tech{quoting depth} is @racket[0].
|
|
|
|
In @racket[print] mode with @racket[print-as-expression] as
|
|
@racket[#t] and a @tech{quoting depth} of @racket[0], the
|
|
structure content is printed with a @litchar{(} followed by
|
|
the structure's type name (as determined by
|
|
@racket[object-name]) in @racket[write] mode; the remaining
|
|
elements are @racket[print]ed at @tech{quoting depth}
|
|
@racket[0] and separated by a space, and finally a closing
|
|
@litchar{)}.
|
|
|
|
A transparent structure type that is not a @tech{prefab}
|
|
structure type is never @tech{quotable}.}
|
|
|
|
@item{For any other structure type, the structure prints as an
|
|
unreadable value; see @secref["print-unreadable"] for more
|
|
information.}
|
|
]
|
|
|
|
If the @racket[print-struct] parameter is set to @racket[#f], then all
|
|
structures without a @racket[prop:custom-write] property print as
|
|
unreadable values (see @secref["print-unreadable"]) and count as
|
|
@tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-hashtable"]{Printing Hash Tables}
|
|
|
|
When the @racket[print-hash-table] parameter is set to @racket[#t], in
|
|
@racket[write] and @racket[display] modes, a @tech{hash table} prints
|
|
starting with @litchar{#hash(}, @litchar{#hasheqv(}, or
|
|
@litchar{#hasheq(} for a table using @racket[equal?], @racket[eqv?],
|
|
or @racket[eq?] key comparisons, respectively. After the prefix, each
|
|
key--value mapping is shown as @litchar{(}, the printed form of a key,
|
|
a space, @litchar{.}, a space, the printed form the corresponding
|
|
value, and @litchar{)}, with an additional space if the key--value
|
|
pair is not the last to be printed. After all key--value pairs, the
|
|
printed form completes with @litchar{)}.
|
|
|
|
In @racket[print] mode when @racket[print-as-expression] is
|
|
@racket[#f] or the @tech{quoting depth} is @racket[1], the printed form
|
|
is the same as for @racket[write]. Otherwise, if the hash table's keys
|
|
and values are all @tech{quotable}, the table prints with a
|
|
@litchar{'} prefix, and the table's key and values are @racket[print]ed
|
|
at @tech{quoting depth} @racket[1]. If some key or value is not
|
|
@tech{quotable}, the hash table prints as @litchar["(hash "],
|
|
@litchar["(hasheqv "], or @litchar["(hasheq "] followed by alternating
|
|
keys and values @racket[print]ed at @tech{quoting depth} @racket[1] and
|
|
separated by spaces, and finally a closing @litchar{)}. A hash table
|
|
is @tech{quotable} when all of its keys and values are
|
|
@tech{quotable}.
|
|
|
|
When the @racket[print-hash-table] parameter is set to @racket[#f], a
|
|
hash table prints as @litchar{#<hash>} and counts as @tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-box"]{Printing Boxes}
|
|
|
|
When the @racket[print-box] parameter is set to @racket[#t], a @tech{box}
|
|
prints as @litchar{#&} followed by the printed form of its content in
|
|
@racket[write], @racket[display], or @racket[print] mode when
|
|
@racket[print-as-expression] is @racket[#f] or the @tech{quoting
|
|
depth} is @racket[1].
|
|
|
|
In @racket[print] mode when @racket[print-as-expression] is
|
|
@racket[#t] and the @tech{quoting depth} is @racket[0], a box prints
|
|
with a @litchar{'} prefix and its value is printed at @tech{quoting
|
|
depth} @racket[1] when its content is @tech{quotable}, otherwise the
|
|
box prints a @litchar["(box "] followed by the content at
|
|
@tech{quoting depth} @racket[0] and a closing @litchar{)}. A box is
|
|
@tech{quotable} when its content is @tech{quotable}.
|
|
|
|
When the @racket[print-box] parameter is set to @racket[#f], a box
|
|
prints as @litchar{#<box>} and counts as @tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-character"]{Printing Characters}
|
|
|
|
@tech{Characters} with the special names described in
|
|
@secref["parse-character"] @racket[write] and @racket[print] using the
|
|
same name. (Some characters have multiple names; the
|
|
@racket[#\newline] and @racket[#\nul] names are used instead of
|
|
@racketvalfont{#\linefeed} and @racketvalfont{#\null}.) Other graphic characters
|
|
(according to @racket[char-graphic?]) @racket[write] as @litchar{#\}
|
|
followed by the single character, and all others characters are
|
|
written in @racket[#\u] notation with four digits or @racket[#\U]
|
|
notation with eight digits (using the latter only if the character
|
|
value does not fit in four digits).
|
|
|
|
All characters @racket[display] directly as themselves (i.e., a single
|
|
character).
|
|
|
|
For the purposes of printing enclosing datatypes, a character is
|
|
@tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-keyword"]{Printing Keywords}
|
|
|
|
@tech{Keywords} @racket[write], @racket[print], and @racket[display] the same
|
|
as symbols (see @secref["print-symbol"]) except with a leading
|
|
@litchar{#:} (after any @litchar{'} prefix added in @racket[print]
|
|
mode), and without special handling for an initial @litchar{#} or when
|
|
the printed form would match a number or a delimited @litchar{.}
|
|
(since @litchar{#:} distinguishes the keyword).
|
|
|
|
For the purposes of printing enclosing datatypes, a keyword is
|
|
@tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-regexp"]{Printing Regular Expressions}
|
|
|
|
@tech{Regexp values} @racket[write], @racket[display], and @racket[print]
|
|
starting with @litchar{#px} (for @racket[pregexp]-based regexps) or
|
|
@litchar{#rx} (for @racket[regexp]-based regexps) followed by the
|
|
@racket[write] form of the regexp's source string or byte string.
|
|
|
|
For the purposes of printing enclosing datatypes, a regexp value is
|
|
@tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-path"]{Printing Paths}
|
|
|
|
@tech{Paths} @racket[write] and @racket[print] as @litchar{#<path:....>}. A
|
|
path @racket[display]s the same as the string produced by
|
|
@racket[path->string]. For the purposes of printing enclosing
|
|
datatypes, a path counts as @tech{quotable}.
|
|
|
|
Although a path can be converted to a string with
|
|
@racket[path->string] or to a byte string with @racket[path->bytes],
|
|
neither is clearly the right choice for printing a path and reading it
|
|
back. If the path value is meant to be moved among platforms, then a
|
|
string is probably the right choice, despite the potential for losing
|
|
information when converting a path to a string. For a path that is
|
|
intended to be re-read on the same platform, a byte string is probably
|
|
the right choice, since it preserves information in an unportable
|
|
way. Paths do not print in a readable way so that programmers are not
|
|
misled into thinking that either choice is always appropriate.
|
|
|
|
|
|
@section[#:tag "print-unreadable"]{Printing Unreadable Values}
|
|
|
|
For any value with no other printing specification, assuming that the
|
|
@racket[print-unreadable] parameter is set to @racket[#t], the output
|
|
form is @litchar{#<}@nonterm{something}@litchar{>}, where
|
|
@nonterm{something} is specific to the type of the value and sometimes
|
|
to the value itself. If @racket[print-unreadable] is set to
|
|
@racket[#f], then attempting to print an unreadable value raises
|
|
@racket[exn:fail].
|
|
|
|
For the purposes of printing enclosing datatypes, a value that prints
|
|
unreadably nevertheless counts as @tech{quotable}.
|
|
|
|
|
|
@section[#:tag "print-compiled"]{Printing Compiled Code}
|
|
|
|
Compiled code as produced by @racket[compile] prints using
|
|
@litchar{#~}. Compiled code printed with @litchar{#~} is essentially
|
|
assembly code for Racket, and reading such a form produces a compiled
|
|
form when the @racket[read-accept-compiled] parameter is set to
|
|
@racket[#t].
|
|
|
|
When a compiled form contains syntax object constants, they must not
|
|
be @tech{tainted} or @tech{armed}; the @litchar{#~}-marshaled form
|
|
drops source-location information and properties (see
|
|
@secref["stxprops"]) for the @tech{syntax objects}.
|
|
|
|
Compiled code parsed from @litchar{#~} may contain references to
|
|
unexported or protected bindings from a module. At read time, such
|
|
references are associated with the current code inspector (see
|
|
@racket[current-code-inspector]), and the code will only execute if
|
|
that inspector controls the relevant module invocation (see
|
|
@secref["modprotect"]).
|
|
|
|
A compiled-form object may contain @tech{uninterned} symbols (see
|
|
@secref["symbols"]) that were created by @racket[gensym] or
|
|
@racket[string->uninterned-symbol]. When the compiled object is read
|
|
via @litchar{#~}, each uninterned symbol in the original form is
|
|
mapped to a new uninterned symbol, where multiple instances of a
|
|
single symbol are consistently mapped to the same new symbol. The
|
|
original and new symbols have the same printed
|
|
representation. @tech{Unreadable symbols}, which are typically
|
|
generated indirectly during expansion and compilation, are saved and
|
|
restored consistently through @litchar{#~}.
|
|
|
|
The dynamic nature of @tech{uninterned} symbols and their localization
|
|
within @litchar{#~} can cause problems when @racket[gensym] or
|
|
@racket[string->uninterned-symbol] is used to construct an identifier
|
|
for a top-level or module binding (depending on how the identifier and
|
|
its references are compiled). To avoid problems, generate distinct
|
|
identifiers either with @racket[generate-temporaries] or by applying
|
|
the result of @racket[make-syntax-introducer] to an existing
|
|
identifier; those functions lead to top-level and module variables
|
|
with @tech{unreadable symbol}ic names, and the names are deterministic
|
|
as long as expansion is otherwise deterministic.
|
|
|
|
Despite the problems inherent with @tech{uninterned} symbols as
|
|
variable names, they are partially supported even across multiple
|
|
@litchar{#~}s: When compiled code contains a reference to a module-defined
|
|
variable whose name is an @tech{uninterned} symbol, the relative
|
|
position of the variable among the module's definitions is recorded,
|
|
and the reference can be linked back to the definition based on its
|
|
position and the characters in its name. This accommodation works only
|
|
for variable references in compiled code; it does not work for
|
|
@racket[syntax]-quoted identifiers, for example.
|
|
|
|
Finally, a compiled form may contain path literals. Although paths are
|
|
not normally printed in a way that can be read back in, path literals
|
|
can be written and read as part of compiled code. The
|
|
@racket[current-write-relative-directory] parameter is used to convert
|
|
the path to a relative path as is it written, and then
|
|
@racket[current-load-relative-directory] parameter is used to convert
|
|
any relative path back as it is read. The relative-path conversion
|
|
applies on reading whether the path was originally relative or not.
|