Guilherme
Guilherme

Reputation: 618

macro: value is not of type LIST

I am trying to write a macro that will eazygnuplot:plot many series at once. Ideally, I wanted to write something like (plotlists lists), where lists looks something like this:

'(((57 91)) ((83 1) (90 8) (78 18)) ((42 19)))

That is, lists is a list of k lists of pairs (more concretely, this is a list of points on a plane, after clustering with k-means). The macro I mentioned is supposed to expand into something like:

(eazy-gnuplot:plot (lambda ()
                     (dolist (p l1)
                       (format t "~&~A ~A" (first p) (second p)))))
(eazy-gnuplot:plot (lambda ()
                     (dolist (p l2)
                       (format t "~&~A ~A" (first p) (second p)))))

...and so forth. My idea was to write something like this:

(defmacro plotlists (lists)
  `(progn ,@(mapcar #'(lambda (ll)
                        '(eazy-gnuplot:plot
                             (lambda ()
                                (dolist (p ll)
                                  (format t "~&~A ~A" (first p) (second p))))))
                    lists)))

That macro is called by a function scatter like this:

(defun scatter (lists)
  (eazy-gnuplot:with-plots (*standard-output* :debug t)
    (eazy-gnuplot:gp-setup :terminal '(:qt))
    (plotlists lists)
    (format t "~&pause mouse button1;~%")))

However, compiling the function on SBCL gives several warnings and errors ("the variable LISTS is defined but never used -- how??"; and "the value LISTS is not of type LIST"). Also, according to the compiler, for some reason, the "~&pause mouse button1;~%" part is "unreachable code" and is deleted on compilation. How come?

I know very little about Lisp, but this is pretty puzzling to me. Anyone have any ideas on that?

Upvotes: 2

Views: 756

Answers (1)

Guilherme
Guilherme

Reputation: 618

So, apparently I was approaching this totally wrong. There's no need to use a macro for that, as made apparent by running MACROEXPAND-1 on the expression. The value of LISTS is not of type LIST because it's just a SYMBOL, which is the only thing available at macro expansion time. I simply replaced the macro with another DOLIST:

(defun scatter (lists)
  (eazy-gnuplot:with-plots (*standard-output* :debug t)
    (eazy-gnuplot:gp-setup :terminal '(:qt))
    (dolist (cluster lists)
      (eazy-gnuplot:plot (lambda ()
                           (dolist (point cluster)
                             (format t "~&~A ~A" (first point) (second point))))))
    (format t "~&pause mouse button1;~%")))

Upvotes: 5

Related Questions