#
Chapter 23
`pconvert.ss`: Converted Printing

This library defines routines for printing Scheme values as `eval`uatable S-expressions rather than `read`able S-expressions. The `print-convert` procedure does not print values; rather, it converts a Scheme value into another Scheme value such that the new value pretty-prints as a Scheme expression that evaluates to the original value. For example, `(pretty-print (print-convert `(9 ,(box 5) #(6 7)))` prints the literal expression `(list 9 (box 5) (vector 6 7))` to the current output port.

To install print converting into the `read`-`eval`-`print` loop, require `pconvert.ss` and call the procedure `install-converting-printer`.

In addition to `print-convert`, this library provides `print-convert`, `build-share`, `get-shared`, and `print-convert-expr`. The last three are used to convert sub-expressions of a larger expression (potentially with shared structure).

`(abbreviate-cons-as-list``` [`abbreviate?`]`)` P R O C E D U R E

Parameter that controls how lists are represented with constructor-style conversion. If the parameter's value is `#t`, lists are represented using `list`. Otherwise, lists are represented using `cons`. The initial value of the parameter is `#t`.

`(booleans-as-true/false``` [`use-name?`]`)` P R O C E D U R E

Parameter that controls how `#t` and `#f` are represented. If the parameter's value is `#t`, then `#t` is represented as `true` and `#f` is represented as `false`. The initial value of the parameter is `#t`.

`(use-named/undefined-handler``` [`use-handler`]`)` P R O C E D U R E

This parameter that controls how values that have inferred names are represented. This parameter is passed a value. If the parameter returns `#t`, the `named/undefined-handler` is invoked to render that value. Only values that have inferred names but are not defined at the top-level are used with this handler.

The initial value of the parameter is `(lambda (x) #f)`.

`(use-named/undefined-handler``` [`use-handler`]`)` P R O C E D U R E

This parameter that controls how values that have inferred names are represented. This parameter is only called if `use-named/undefined-handler` returned true for some value. This parameter is passed that same value and the result of the parameter is used as the representation for the value.

The initial value of the parameter is `(lambda (x) #f)`.

`(build-share``` `v``)` P R O C E D U R E

Takes a value and computes sharing information used for representing the value as an expression. The return value is an opaque structure that can be passed back into `get-shared` or `print-convert-expr`.

`(constructor-style-printing``` [`use-constructors?`]`)` P R O C E D U R E

Parameter that controls how values are represented after conversion. If this parameter is `#t`, then constructors are used, e.g., pair containing 1 and 2 is represented as `(cons 1 2)`. Otherwise, quasiquote-style syntax is used, e.g. the pair containing 1 and 2 is represented as ``(1 . 2)`. The initial value of the parameter is `#f`.

See also `quasi-read-style-printing`.

`(current-build-share-hook``` [`hook`]`)` P R O C E D U R E

Parameter that sets a procedure used by `print-convert` and `build-share` to assemble sharing information. The procedure `hook` takes three arguments: a value `v`, a procedure `basic-share`, and a procedure `sub-share`; the return value is ignored. The `basic-share` procedure takes `v` and performs the built-in sharing analysis, while the `sub-share` procedure takes a component of `v` ands analyzes it. These procedures return void; sharing information is accumulated as values are passed to `basic-share` and `sub-share`.

A `current-build-share-hook` procedure usually works together with a `current-print-convert-hook` procedure.

`(current-build-share-name-hook``` [`hook`]`)` P R O C E D U R E

Parameter that sets a procedure used by `print-convert` and `build-share` to generate a new name for a shared value. The `hook` procedure takes a single value and returns a symbol for the value's name. If `hook` returns `#f`, a name is generated using the form ```-`n`-`'' (where `n` is an integer).

`(current-print-convert-hook``` [`hook`]`)` P R O C E D U R E

Parameter that sets a procedure used by `print-convert` and `print-convert-expr` to convert values. The procedure `hook` takes three arguments -- a value `v`, a procedure `basic-convert`, and a procedure `sub-convert` -- and returns the converted representation of `v`. The `basic-convert` procedure takes `v` and returns the default conversion, while the `sub-convert` procedure takes a component of `v` and returns its conversion.

A `current-print-convert-hook` procedure usually works together with a `current-build-share-hook` procedure.

`(current-read-eval-convert-print-prompt``` [`str`]`)` P R O C E D U R E

Parameter that sets the prompt used by `install-converting-printer`. The initial value is `"|- "`.

`(get-shared``` `share-info``` [`cycles-only?`]`)` P R O C E D U R E

The `shared-info` value must be a result from `build-share`. The procedure returns a list matching variables to shared values within the value passed to `build-share`. For example, ``

(get-shared (build-share (shared ([a (cons 1 b)][b (cons 2 a)]) a)))

might return the list ``

((-1- (cons 1 -2-)) (-2- (cons 2 -1-)))

The default value for `cycles-only?` is `#f`; if it is not `#f`, `get-shared` returns only information about cycles.

`(install-converting-printer``)` P R O C E D U R E

Sets the current print handler to print values using `print-convert`. The current read handler is also set to use the prompt returned by `current-read-eval-convert-print-prompt`.

`(print-convert``` `v``` [`cycles-only?`]`)` P R O C E D U R E

Converts the value `v`. If `cycles-only?` is not `#f`, then only circular objects are included in the output. The default value of `cycles-only?` is the value of `(show-sharing)`.

`(print-convert-expr``` `share-info v unroll-once?``)` P R O C E D U R E

Converts the value `v` using sharing information `share-info` previously returned by `build-share` for a value containing `v`. If the most recent call to `get-shared` with `share-info` requested information only for cycles, then `print-convert-expr` will only display sharing among values for cycles, rather than showing all value sharing.

The `unroll-once?` argument is used if `v` is a shared value in `share-info`. In this case, if `unroll-once?` is `#f`, then the return value will be a shared-value identifier; otherwise, the returned value shows the internal structure of `v` (using shared value identifiers within `v`'s immediate structure as appropriate).

`(quasi-read-style-printing``` [`on?`]`)` P R O C E D U R E

Parameter that controls how vectors and boxes are represented after conversion when the value of `constructor-style-printing` is `#f`. If `quasi-read-style-printing` is set to `#f`, then boxes and vectors are unquoted and represented using constructors. For example, the list of a box containing the number 1 and a vector containing the number 1 is represented as ``(,(box 1) ,(vector 1))`. If the parameter is `#t`, then `#&` and `#()` are used, e.g., ``(#&1 #(1))`. The initial value of the parameter is `#t`.

`(show-sharing``` [`show?`]`)` P R O C E D U R E

Parameter that determines whether sub-value sharing is conserved (and shown) in the converted output by default. The initial value of the parameter is `#t`.

`(whole/fractional-exact-numbers``` [`whole-frac?`]`)` P R O C E D U R E

Parameter that controls how exact, non-integer numbers are converted when the numerator is greater than the denominator. If the parameter's value is `#t`, the number is converted to the form `(+ `integer` `fraction`)` (i.e., a list containing `'+`, an exact integer, and an exact rational less than `1` and greater than `-1`). The initial value of the parameter is `#f`.