John Graham
John Graham

Reputation: 499

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?

Upvotes: 2

Views: 468

Answers (2)

Víctor Ponce
Víctor Ponce

Reputation: 1

I think you just defined two inputs for the macro, &body and body since they are both valid symbols names, so it's logic to ask for two arguments.

https://www.gnu.org/software/emacs/manual/html_node/elisp/Symbol-Type.html

Upvotes: 0

phils
phils

Reputation: 73345

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.

Upvotes: 4

Related Questions