Search code examples
macroscommon-lisppretty-printlisp-macros

Why this macro to pretty print macro expansions in Common Lisp does not work? What are the alternatives tools for this?


I am trying to learn Common Lisp with the book Common Lisp: A gentle introduction to Symbolic Computation. In addition, I am using SBCL, Emacs, and Slime.

In chapter 14, the last one, the author covers macros. He presents a tool called PPMX which stands for: ‘‘Pretty Print Macro eXpansion’’.

With this tool, you can do:

> (ppmx (incf a))
Macro expansion:
(SETQ A (+ A 1))

The tool is self-contained since the book provides the code definition for it:

(defmacro ppmx (form)
  "Pretty prints the macro expansion of FORM."
  ‘(let* ((exp1 (macroexpand-1 ’,form))
          (exp (macroexpand exp1))
          (*print-circle* nil))
     (cond ((equal exp exp1)
            (format t "~&Macro expansion:")
            (pprint exp))
           (t (format t "~&First step of expansion:")
              (pprint exp1)
              (format t "~%~%Final expansion:")
              (pprint exp)))
     (format t "~%~%")
     (values)))

Unfortunately, I cannot run it because the compilation does not work. The Slime's REPL throws this error:

ch-14.lisp:3:33:
  read-error: 
    READ error during COMPILE-FILE:
    
      Comma not inside a backquote.
    
        Line: 3, Column: 33, File-Position: 101
    
        Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /tmp/slimeD4xBr3" {10036BFC63}>

Compilation failed.

The comma and left single quote look different in emacs than in SO: enter image description here

I have had some problems when copying the code from the book to emacs. It was basically inserting ' instead of the left single quote.

1 - Is there a way to fix this?

2 - The book was written in the late 1980s. Thus, I bet there are better tools now. Does Slime or SBCL offer some command to pretty print macro expansions? Maybe a library or another package?

Thanks.


Solution

  • Following @barmar's advice, the user just need to write in the REPL:

    CL-USER> *print-pretty*
    T
    CL-USER> (macroexpand (setf a 1))  ;without the quote it does not work
    1
    NIL
    CL-USER> (macroexpand '(setf a 1)) ;with the quote it does
    (SETQ A 1)
    T