I'm attempting to write a program in Common Lisp that dynamically creates other lisp files. Common Lisp's print
function seems very useful for this purpose. Unfortunately, the function outputs data on a single line. For example (just printing to standard output):
(print '(let ((a 1) (b 2) (c 3)) (+ a b c)))
>> (let ((a 1) (b 2) (c 3)) (+ a b c))
The generated lisp files need to be human readable and thus shouldn't minimize whitespace. It seems that the pprint
function is the solution to my problem. Since pprint sets *pretty-print*
to true, the function should print on multiple lines. In other words:
(pprint '(let ((a 1) (b 2) (c 3)) (+ a b c)))
>> (let ((a 1)
>> (b 2)
>> (c 3))
>> (+ a b c))
However, in Allegro CL, pprint seems to behave in an identical manner to print. Output is only on a single line. Is there a way to cause the function to print s-expressions in a "pretty" way? Are there any other globals that need to be set before the function prints correctly? Is there an alternative function/macro that I'm looking for? Thanks for the help!
The pretty printer is controlled by more than just *print-pretty*. E.g., look at the interaction with *print-right-margin* in SBCL (under SLIME):
CL-USER> (pprint '(let ((a 1) (b 2) (c 3)) (+ a b c)))
(LET ((A 1) (B 2) (C 3))
(+ A B C))
; No value
CL-USER> (let ((*print-right-margin* 10))
(pprint '(let ((a 1) (b 2) (c 3)) (+ a b c))))
(LET ((A
1)
(B
2)
(C
3))
(+ A B
C))
; No value
CL-USER> (let ((*print-right-margin* 20))
(pprint '(let ((a 1) (b 2) (c 3)) (+ a b c))))
(LET ((A 1)
(B 2)
(C 3))
(+ A B C))
; No value
You might be able to get satisfactory results just by setting that variable, but in general you'll want to have a look at 22.2 The Lisp Pretty Printer. Pretty printing functions have lots of places for optional newlines and the like, and where they get put depends on a number of things (like *print-right-margin* and *print-miser-width*). There are some examples of using the pretty printer to format Lisp source code in 22.2.2 Examples of using the Pretty Printer. There's too much to quote it all, but it shows how the following pretty printing code can produce all these outputs, depending on context:
(defun simple-pprint-defun (*standard-output* list)
(pprint-logical-block (*standard-output* list :prefix "(" :suffix ")")
(write (first list))
(write-char #\Space)
(pprint-newline :miser)
(pprint-indent :current 0)
(write (second list))
(write-char #\Space)
(pprint-newline :fill)
(write (third list))
(pprint-indent :block 1)
(write-char #\Space)
(pprint-newline :linear)
(write (fourth list))))
(DEFUN PROD (X Y)
(* X Y))
(DEFUN PROD
(X Y)
(* X Y))
(DEFUN
PROD
(X Y)
(* X Y))
;;; (DEFUN PROD
;;; (X Y)
;;; (* X Y))