Reputation: 618
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
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