Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expand a macro form completely

I'd like to learn the internals of Lisp, so I want to see how everything is implemented.

For example,

(macroexpand '(loop for i upto 10 collect i))

gives me (in SBCL)

(BLOCK NIL
  (LET ((I 0))
    (DECLARE (TYPE (AND NUMBER REAL) I))
    (SB-LOOP::WITH-LOOP-LIST-COLLECTION-HEAD (#:LOOP-LIST-HEAD-1026
                                              #:LOOP-LIST-TAIL-1027)
      (SB-LOOP::LOOP-BODY NIL
                          (NIL NIL (WHEN (> I '10) (GO SB-LOOP::END-LOOP)) NIL)
                          ((SB-LOOP::LOOP-COLLECT-RPLACD
                            (#:LOOP-LIST-HEAD-1026 #:LOOP-LIST-TAIL-1027)
                            (LIST I)))
                          (NIL (SB-LOOP::LOOP-REALLY-DESETQ I (1+ I))
                           (WHEN (> I '10) (GO SB-LOOP::END-LOOP)) NIL)
                          ((RETURN-FROM NIL
                             (SB-LOOP::LOOP-COLLECT-ANSWER
                              #:LOOP-LIST-HEAD-1026)))))))

But LOOP-BODY, WITH-LOOP-LIST-COLLECTION-HEAD, etc. are still macros. How can I expand a macro form completely?

like image 391
Mike Manilone Avatar asked May 16 '13 05:05

Mike Manilone


People also ask

How are macros expanded in C?

The LENGTH and BREADTH are called the macro templates. The values 10 and 20 are called macro expansions. When the program run and if the C preprocessor sees an instance of a macro within the program code, it will do the macro expansion. It replaces the macro template with the value of macro expansion.

How do I expand a macro in Splunk search?

After the search has run, tap SHIFT-CTL-E to E xpand macros. If there are any nested macros inside of macros, run that expanded search and do the same thing, deeper and deeper.


2 Answers

To see the full expansion one needs to walk the Lisp form on all levels and expand them. For this it is necessary that this so-called code walker understands Lisp syntax (and not just s-expression syntax). For example in (lambda (a b) (setf a b)), the list (a b) is a parameter list and should not be macro expanded.

Various Common Lisp implementations provide such a tool. The answer of 6502 mentions MACROEXPAND-ALL which is provided by SBCL.

If you use a development environment, it is usually provided as a command:

  • SLIME: M-x slime-macroexpand-all with C-c M-m

  • LispWorks: menu Expression > Walk or M-x Walk Form, shorter M-Sh-m.

like image 59
Rainer Joswig Avatar answered Sep 21 '22 09:09

Rainer Joswig


The other answers are excellent for you question but you say you want to see how everything is implemented.

Many macros (as you know already) are implemented using macros and whilst macroexpand-all is very useful but you can lose the context of what macro was responsible for what change.

One nice middle ground (if you are using slime) is to use slime-expand-1 (C-c Enter) which shows the expansion is another buffer. You can then useslime-expand-1 inside this new buffer to expand macros in-place. This allows you to walk the tree expanding as you read and also to use undo to close the expansions again.

For me this has been a god-send in understanding other people's macros. Hope this helps you too, have fun!

like image 29
Baggers Avatar answered Sep 21 '22 09:09

Baggers