2015-10-15 39 views
2

我正在嘗試編寫一個宏,它將一起eazygnuplot:plot許多系列。理想情況下,我想寫類似(plotlists lists),其中lists看起來是這樣的:宏:值不是類型LIST

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

也就是說,lists是對k名單列表(更具體地說,這是點在一個平面上的列表,用k-means聚類後)。我提到的宏應該擴展成如下形式:

(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))))) 

...等等。我的想法是寫的東西是這樣的:

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

該宏由函數scatter這樣調用:

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

然而,編譯於SBCL的功能給出了一些警告和錯誤(「變量LISTS被定義但從未被使用 - 如何?「和」LISTS的值不是LIST類型「)。此外,根據編譯器,出於某種原因,"~&pause mouse button1;~%"部分是「不可到達的代碼」,並在編譯時被刪除。怎麼來的?

我對Lisp知之甚少,但這對我來說很讓人費解。任何人有任何想法?

回答

4

所以,顯然我接近完全錯誤。沒有必要爲此使用宏,就像在表達式上運行MACROEXPAND-1一樣。 LISTS的值不是LIST,因爲它只是一個SYMBOL,這是宏擴展時唯一可用的。我簡單地用另一個替換宏: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;~%"))) 
相關問題