Take the 2-minute tour ×

I'm wondering how the case macro works, but just expanding it is not enough. How does it generate the cond statement without knowing how many arguments there are? Does it use a loop or something? And if so then why does it not show up when i run macroexpand.

I need to write something that works in a similar way, that's why I ask.

share|improve this question
Why not look in the source code of your favourite implementation? –  Le Petit Prince Jan 5 at 13:12

1 Answer 1

Yes you would need to use iteration - one of loop, do, mapcar &c (or recursion).

Take a look at, e.g., CLISP's implementation of case:

(defun case-expand (whole-form form-name test keyform clauses)
  (let ((var (gensym (string-concat (symbol-name form-name) "-KEY-"))))
    `(let ((,var ,keyform))
           #'(lambda (remaining-clauses)
               (let ((clause (first remaining-clauses))
                     (remaining-clauses (rest remaining-clauses)))
                 (unless (consp clause)
                   (error-of-type 'source-program-error
                     :form whole-form
                     :detail clause
                     (TEXT "~S: missing key list")
                 (let ((keys (first clause)))
                   `(,(cond ((or (eq keys 'T) (eq keys 'OTHERWISE))
                             (if remaining-clauses
                                 (error-of-type 'source-program-error
                                   :form whole-form
                                   :detail clause
                                   (TEXT "~S: the ~S clause must be the last one")
                                   form-name keys)
                            ((listp keys)
                             `(or ,@(mapcar #'(lambda (key)
                                                `(,test ,var ',key))
                            (t `(,test ,var ',keys)))
                     ,@(rest clause)))))

(defmacro case (&whole whole-form
                keyform &body clauses)
  (case-expand whole-form 'case 'eql keyform clauses))
share|improve this answer
Note that some recursive approaches to this wouldn't be explicit. For instance, case could expand into an if that checked the first case and left the else part as (case ...). The macro definition wouldn't be explicitly recursive. –  Joshua Taylor Jan 5 at 22:37

Your Answer


