2013-10-16 49 views
5

我認爲傳遞給lisp函數的值被分配給與參數名匹配的報價。不過,我很驚訝這樣的:函數參數如何存儲在lisp中?

(defun test (x) (print (eval 'x))) 
(test 5) 

不起作用(變量x是未綁定的)。所以如果參數沒有作爲符號存儲在函數中,那麼在這個例子中究竟是什麼?有沒有辦法從符合參數名稱的符號訪問參數?

更多背景: 我想要做的是這樣的:

defun slice (r1 c1 r2 c2 board) 
    (dolist (param '(r1 c1 r2 c2)) ;adjust for negative indices 
    (if (< (eval param) 0) 
     (set param (+ (length board) (eval param))))) 
     ;Body of function 

基本上,我想通過前四個參數,如果他們是<迭代並作出調整的所有值0.當然,我可以爲每個參數做一個獨立的行,但考慮到我對四個參數中的每一個都做了同樣的事情,這看起來更清晰。 但是,我收到了變量R1未被綁定的錯誤。

+0

它是具體實施。 [SBCL(http://www.sbcl.org/manual/index.html)提供一些信息,在外國功能接口章等 –

回答

4

有從匹配參數名稱的符號訪問參數的方法嗎?

不詞法綁定。 Common Lisp無法從類似的命名符號訪問詞法變量。您需要聲明變量特殊

因此,如果參數沒有作爲符號存儲在函數中,那麼在這個例子中究竟是什麼?

處理器寄存器?堆棧框架的一部分?

動態綁定:

CL-USER 40 > (defun foo (a b) 
       (declare (special a b)) 
       (dolist (v '(a b)) 
       (if (zerop (symbol-value v)) 
        (set v 10))) 
       (values a b)) 
FOO 

CL-USER 41 > (foo 1 0) 
1 
10 
+0

謝謝,這允許我使用相同的代碼只有一個額外的行申報作爲特殊參數 – rcorre

+2

@murphyslaw確保您瞭解聲明特殊變量的其他可能後果。變量將與動態範圍,這意味着,例如所束縛,該'(讓((×3))(聲明(特殊的X))(funcall(讓((×4))(聲明(特殊的X))...(拉姆達( )x))))''會返回'3',而不是'4',即使當創建'lambda'函數'x'綁定到'4'時。 –

+0

@JoshuaTaylor - 非常感謝您的支持,我顯然需要做更多的閱讀。可以肯定的是,將參數聲明爲特殊參數不會影響功能塊外部的該符號,是正確的嗎? – rcorre

2

正如雷納解釋的,你不能訪問它的名字詞法參數值。

你可以做的反而是,如果你想要的變量太多連同destructuring-bind使用&rest參數:

(defun slice (board &rest params) 
    (destructuring-bind (r1 c1 r2 c2) 
     (mapcar (lambda (param) ;adjust for negative indices 
       (if (minusp param) 
        (+ (length board) param) 
        param)) 
       params) 
    ... operate on r1 c1 r2 c2 ...)) 
5

這基本上綁定工作,如何詞法:變量名被詞法範圍內替換爲直接引用變量值的存儲位置。綁定變量名的symbol-value僅針對您可以用special聲明動態變量來完成。

的一種方式,以避免重蹈自己將是一個宏:

(defmacro with-adjusting ((&rest vars) adjust-value &body body) 
    `(let ,(loop for var in vars 
       collect `(,var (if (minusp ,var) 
           (+ ,var ,adjust-value) 
           ,var))) 
    ,@body)) 

(defun slice (r1 c1 r2 c2 board) 
    (with-adjusting (r1 c1 r2 c2) (length board) 
    ;; function body 
+1

這是一個很好的答案。宏在這裏非常有用。小缺點:編譯後的代碼變大。 –

相關問題