#
Chapter 30
`pconvert.ss`: Converted Printing

To load: `(require (lib "pconvert.ss"))`

This library defines routines for printing Scheme values as `eval`uable 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).

See also `prop:print-convert-constructor-name` in section 31.

`(abbreviate-cons-as-list``` [`abbreviate?`]`)` PROCEDURE

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?`]`)` PROCEDURE

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`]`)` PROCEDURE

Parameter for a procedure that controls how values that have inferred names are represented. The procedure is passed a value. If the parameter returns `#t`, the procedure associated with `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)`.

`(named/undefined-handler``` [`use-handler`]`)` PROCEDURE

Parameter for a procedure that controls how values that have inferred names are represented. The procedure is called only if `use-named/undefined-handler` returns true for some value. In that case, the procedure 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``)` PROCEDURE

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?`]`)` PROCEDURE

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`, and see `prop:print-convert-constructor-name` in section 31.

`(current-build-share-hook``` [`hook`]`)` PROCEDURE

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`]`)` PROCEDURE

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`]`)` PROCEDURE

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`]`)` PROCEDURE

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

`(get-shared``` `share-info``` [`cycles-only?`]`)` PROCEDURE

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``)` PROCEDURE

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?`]`)` PROCEDURE

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?``)` PROCEDURE

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?`]`)` PROCEDURE

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?`]`)` PROCEDURE

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?`]`)` PROCEDURE

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`.