Why are standard macros so complicated

Discussion of Common Lisp
Post Reply
porky11
Posts: 25
Joined: Fri May 02, 2014 6:46 am

Why are standard macros so complicated

Post by porky11 » Fri May 02, 2014 7:04 am

I'm new at this forum and have a question about the standard macros in common lisp.
When I macroexpand them, they include more let/let* than necessary and many functions, macros or tags (in tagbodys) I would normally not use. ('dolist in sbcl for example contains a truly-the macro)
If I define my own 'dolist macro I would write something like this:

Code: Select all

(defmacro my-dolist (list &body body)
  (let ((x (car list)) (list (cadr list)))
   `(let ((,x nil) (list ,list))
      (tagbody
      start
        (setq ,x (car list))
        (setq list (cdr list))
        ,@body
        (if list (go start))))))
If I check the time of my own macro, it is normally faster than the inbuilt 'dolist macro. Why doesn't sbcl (or clisp etc.) implement it the same way?

edgar-rft
Posts: 226
Joined: Fri Aug 06, 2010 6:34 am
Location: Germany

Re: Why are standard macros so complicated

Post by edgar-rft » Sat May 03, 2014 1:19 pm

porky11 wrote:If I check the time of my own macro, it is normally faster than the inbuilt 'dolist macro. Why doesn't sbcl (or clisp etc.) implement it the same way?
Try the following code with your macro and see what happens. Then try the same with CL's DOLIST to see the difference:

Code: Select all

(let ((list '(1 2 3)))
  (my-dolist (x '(4 5 6))
    (print (+ x (pop list)))))
Then see Paul Graham's "On Lisp", Chapter 9 Variable Capture, especially Section 9.6 Avoiding Capture with Gensyms.

Your macro also misses the RESULT-FORM argument to DOLIST, the implict BLOCK named NIL, and the proper handling of RETURN and RETURN-FROM within the body.

The Common Lisp standard macros are part of the built-in Common Lisp "standard library" and must be prepared to be expanded in all imaginable situations and environments (even in scope of user-defined classes, types, and condition handlers), so you often see a plethora of bloat in the macroexpansions. But the Common Lisp compiler usually is capable to find and remove unused parts when compiling the expanded code.

- edgar

Post Reply