User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:macros:pprint-logical-block [2019/09/14 05:00]
cl:macros:pprint-logical-block [2019/09/22 06:00] (current)
Line 1: Line 1:
 +====== Macro PPRINT-LOGICAL-BLOCK ======
 +
 +====Syntax====
 +  * **pprint-logical-block** (//​stream-symbol//​ //object// ''&​key''​ //prefix// //​per-line-prefix//​ //suffix//) //​declaration//''​*''​ //​form//''​*''​ → **[[CL:​Constant Variables:​nil]]**
 +
 +====Arguments and Values====
 +  * //​stream-symbol//​ - a //​[[CL:​Glossary:​stream variable designator]]//​.
 +  * //object// - an //​[[CL:​Glossary:​object]]//;​ evaluated.
 +  * //prefix// - a //​[[CL:​Glossary:​string]]//;​ evaluated. Complicated defaulting behavior; see below.
 +  * //​per-line-prefix//​ - a //​[[CL:​Glossary:​string]]//;​ evaluated. Complicated defaulting behavior; see below. ​
 +  * //suffix// - a //​[[CL:​Glossary:​string]]//;​ evaluated. The default is the //​[[CL:​Glossary:​null]]//​ //​[[CL:​Glossary:​string]]//​.
 +  * //​declaration//​ - a **[[CL:​Symbols:​declare]]** //​[[CL:​Glossary:​expression]]//;​ not evaluated.
 +  * //forms// - an //​[[CL:​Glossary:​implicit progn]]//.
 +
 +====Description====
 +Causes printing to be grouped into a logical block.
 +
 +The logical block is printed to the //​[[CL:​Glossary:​stream]]//​ that is the //​[[CL:​Glossary:​value]]//​ of the //​[[CL:​Glossary:​variable]]//​ denoted by //​stream-symbol//​. During the execution of the //​[[CL:​Glossary:​forms]]//,​ that //​[[CL:​Glossary:​variable]]//​ is //​[[CL:​Glossary:​bound]]//​ to a //​[[CL:​Glossary:​pretty printing stream]]// that supports decisions about the arrangement of output and then forwards the output to the destination stream.
 +
 +All the standard printing functions (//e.g.// **[[CL:​Functions:​write]]**,​ **[[CL:​Functions:​princ]]**,​ and **[[CL:​Functions:​terpri]]**) can be used to print output to the //​[[CL:​Glossary:​pretty printing stream]]//. All and only the output sent to this //​[[CL:​Glossary:​pretty printing stream]]// is treated as being in the logical block.
 +
 +The //prefix// specifies a prefix to be printed before the beginning of the logical block. The //​per-line-prefix//​ specifies a prefix that is printed before the block and at the beginning of each new line in the block. The **'':​prefix''​** and **'':​pre-line-prefix''​** //​[[CL:​Glossary:​arguments]]//​ are mutually exclusive. If neither **'':​prefix''​** nor **'':​per-line-prefix''​** is specified, a //prefix// of the //​[[CL:​Glossary:​null]]//​ //​[[CL:​Glossary:​string]]//​ is assumed.
 +
 +The //suffix// specifies a suffix that is printed just after the logical block.
 +
 +The //object// is normally a //​[[CL:​Glossary:​list]]//​ that the body //forms// are responsible for printing. If //object// is not a //​[[CL:​Glossary:​list]]//,​ it is printed using **[[CL:​Functions:​write]]**. (This makes it easier to write printing functions that are robust in the face of malformed arguments.) If **[[CL:​Variables:​star-print-circle-star|*print-circle*]]** is //​[[CL:​Glossary:​non-nil]]//​ and //object// is a circular (or shared) reference to a //​[[CL:​Glossary:​cons]]//,​ then an appropriate ''#​n#''​ marker is printed. (This makes it easy to write printing functions that provide full support for circularity and sharing abbreviation.) If **[[CL:​Variables:​star-print-level-star|*print-level*]]** is not **[[CL:​Constant Variables:​nil]]** and the logical block is at a dynamic nesting depth of greater than **[[CL:​Variables:​star-print-level-star|*print-level*]]** in logical blocks, ''#''​ is printed. (This makes easy to write printing functions that provide full support for depth abbreviation.)
 +
 +If either of the three conditions above occurs, the indicated output is printed on //​stream-symbol//​ and the body //forms// are skipped along with the printing of the **'':​prefix''​** and **'':​suffix''​**. (If the body //forms// are not to be responsible for printing a list, then the first two tests above can be turned off by supplying **[[CL:​Constant Variables:​nil]]** for the //object// argument.)
 +
 +In addition to the //object// argument of **pprint-logical-block**,​ the arguments of the standard printing functions (such as **[[CL:​Functions:​write]]**,​ **[[CL:​Functions:​print]]**,​ **[[CL:​Functions:​prin1]]**,​ and **[[CL:​Functions:​pprint]]**,​ as well as the arguments of the standard //​[[CL:​Glossary:​format directives]]//​ such as ''​~A'',​ ''​~S'',​ (and ''​~W''​) are all checked (when necessary) for circularity and sharing. However, such checking is not applied to the arguments of the functions **[[CL:​Functions:​write-line]]**,​ **[[CL:​Functions:​write-string]]**,​ and **[[CL:​Functions:​write-char]]** or to the literal text output by **[[CL:​Functions:​format]]**. A consequence of this is that you must use one of the latter functions if you want to print some literal text in the output that is not supposed to be checked for circularity or sharing.
 +
 +The body //forms// of a **pprint-logical-block** //​[[CL:​Glossary:​form]]//​ must not perform any side-effects on the surrounding environment;​ for example, no //​[[CL:​Glossary:​variables]]//​ must be assigned which have not been //​[[CL:​Glossary:​bound]]//​ within its scope.
 +
 +The **pprint-logical-block** //​[[CL:​Glossary:​macro]]//​ may be used regardless of the //​[[CL:​Glossary:​value]]//​ of **[[CL:​Variables:​star-print-pretty-star|*print-pretty*]]**.
 +
 +====Examples====
 +None.
 +
 +====Side Effects====
 +None.
 +
 +====Affected By====
 +**[[CL:​Variables:​star-print-circle-star|*print-circle*]]**,​ **[[CL:​Variables:​star-print-level-star|*print-level*]]**.
 +
 +====Exceptional Situations====
 +An error of type **[[CL:​Types:​type-error]]** is signaled if any of the **'':​suffix''​**,​ **'':​prefix''​**,​ or **'':​per-line-prefix''​** is supplied but does not evaluate to a //​[[CL:​Glossary:​string]]//​.
 +
 +An error is signaled if **'':​prefix''​** and **'':​pre-line-prefix''​** are both used.
 +
 +**pprint-logical-block** and the //​[[CL:​Glossary:​pretty printing stream]]// it creates have //​[[CL:​Glossary:​dynamic extent]]//. The consequences are undefined if, outside of this extent, output is attempted to the //​[[CL:​Glossary:​pretty printing stream]]// it creates.
 +
 +It is also unspecified what happens if, within this extent, any output is sent directly to the underlying destination stream.
 +
 +====See Also====
 +  * **[[CL:​Macros:​pprint-pop|Local Macro PPRINT-POP]]**,​
 +  * **[[CL:​Macros:​pprint-exit-if-list-exhausted|Local Macro PPRINT-EXIT-IF-LIST-EXHAUSTED]]**,​
 +  * {\secref\TildeLessThanLogicalBlock}
 +
 +====Notes====
 +One reason for using the **pprint-logical-block** //​[[CL:​Glossary:​macro]]//​ when the //​[[CL:​Glossary:​value]]//​ of **[[CL:​Variables:​star-print-pretty-star|*print-pretty*]]** is **[[CL:​Constant Variables:​nil]]** would be to allow it to perform checking for //​[[CL:​Glossary:​dotted lists]]//, as well as (in conjunction with **[[CL:​Macros:​pprint-pop]]**) checking for **[[CL:​Variables:​star-print-level-star|*print-level*]]** or **[[CL:​Variables:​star-print-length-star|*print-length*]]** being exceeded.
 +
 +Detection of circularity and sharing is supported by the //​[[CL:​Glossary:​pretty printer]]// by in essence performing requested output twice. On the first pass, circularities and sharing are detected and the actual outputting of characters is suppressed. On the second pass, the appropriate ''#​n=''​ and ''#​n#''​ markers are inserted and characters are output. This is why the restriction on side-effects is necessary. Obeying this restriction is facilitated by using **[[CL:​Macros:​pprint-pop]]**,​ instead of an ordinary **[[CL:​Macros:​pop]]** when traversing a list being printed by the body //forms// of the **pprint-logical-block** //​[[CL:​Glossary:​form]]//​.)
 +
 +\issue{GENERALIZE-PRETTY-PRINTER:​UNIFY} \issue{DECLS-AND-DOC} \issue{PRETTY-PRINT-INTERFACE} \issue{GENERALIZE-PRETTY-PRINTER:​UNIFY} \issue{GENERALIZE-PRETTY-PRINTER:​UNIFY}