Search code examples
elispelisp-macro

Elisp: defmacro with &body and &rest behave differently?


I thought &body and &rest were supposed to behave the same, so this puzzled me:

ELISP> (defmacro mrest (&rest rest))                                                                                                                                                                                              
mrest                                                                                                                                                                                                                             
ELISP> (mrest)                                                                                                                                                                                                                    
nil                                                                                                                                                                                                                               
ELISP> (mrest 1)                                                                                                                                                                                                                  
nil                                                                                                                                                                                                                               
ELISP> (mrest 1 2)                                                                                                                                                                                                                
nil                                                                                                                                                                                                                               
ELISP> (mrest 1 2 3)                                                                                                                                                                                                              
nil                                                                                                                                                                                                                               
ELISP> (mrest 1 2 3 4)                                                                                                                                                                                                            
nil                                                                                                                                                                                                                               
ELISP> (defmacro mbody (&body body))                                                                                                                                                                                              
mbody                                                                                                                                                                                                                             
ELISP> (mbody)                                                                                                                                                                                                                    
*** Eval error ***  Wrong number of arguments: (lambda (&body body) nil), 0                                                                                                                                                       
ELISP> (mbody 1)                                                                                                                                                                                                                  
*** Eval error ***  Wrong number of arguments: (lambda (&body body) nil), 1                                                                                                                                                       
ELISP> (mbody 1 2)                                                                                                                                                                                                                
nil                                                                                                                                                                                                                               
ELISP> (mbody 1 2 3)                                                                                                                                                                                                              
*** Eval error ***  Wrong number of arguments: (lambda (&body body) nil), 3                                                                                                                                                       
ELISP> (mbody 1 2 3 4)                                                                                                                                                                                                            
*** Eval error ***  Wrong number of arguments: (lambda (&body body) nil), 4                                                                                                                                                       

Why does elisp insist on mbody having exactly two arguments here?


Solution

  • The Emacs Lisp defmacro doesn't support &body at all. Therefore in your example, &body is the name of one of two mandatory arguments.

    You want the cl-lib variant, cl-defmacro.