Page 1 of 1

Why are standard macros so complicated

Posted: Fri May 02, 2014 7:04 am
by porky11
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?

Re: Why are standard macros so complicated

Posted: Sat May 03, 2014 1:19 pm
by edgar-rft
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