2011-09-12 43 views

回答

8

函數和變量位於Common Lisp中的不同名稱空間中。

因此,當您在預期函數的位置(即正在評估的列表的開頭)使用某個名稱時,它會查找具有該名稱的函數(或宏)。如果在需要變量的位置使用相同的名稱,它會查找具有該名稱的變量。

在你的情況下,有一個名爲numberp的函數,但不是名爲numberp的變量,所以第二種情況會導致錯誤。

+2

可能很好的做法是在不調用實際函數'numberp'的情況下,CL中的語法是'#'numberp'。 – 6502

11

這個問題已經有點不對了。

我們都在談論的Common Lisp不同的事情:

  • 符號:這是在Lisp中的數據結構。符號是具有名稱,值,函數,包和可能更多的數據對象。

在通用Lisp中,符號可以同時具有值​​和函數(或宏)。

  • 一個可變是在Lisp代碼爲一個值的標識符

有由DEFVAR和DEFPARAMETER定義頂級變量。還有LAMBDA,DEFUN,LET,LET *等定義的局部變量。

(defun foo (i-am-a-variable) ...) 

(defparameter *i-am-a-global-variable* ...) 
  • 名爲功能爲在Lisp代碼的功能的標識符。命名函數由DEFUN,DEFGENERIC和DEFMETHOD在頂層引入。也有由FLET和LABELS定義的本地命名函數。

實施例:

(defun i-am-a-function (foo) ...) 

(flet ((i-am-a-function (foo) ...)) ...) 

爲了進一步複雜化的函數名和變量名是在源代碼中的符號。

例子:

(type-of (second '(defun foo() nil))) --> SYMBOL 

讓我們來看看函數和變量:

(defun foo() 
    (let ((some-name 100)) 
    (flet ((some-name (bar) (+ bar 200))) 
     (+ some-name (some-name some-name))))) 

上面代碼中使用的變量,並在源代碼中的相同符號的功能。由於函數和變量都有自己的名稱空間,因此不會發生衝突。

(+ some-name (some-name some-name)) 

上面則表示我們將變量添加到變量的函數調用結果中。

這樣做,你可以這樣做的實際效果:

(defun parent (person) ...) 

(defun do-something (parent) 
    (parent parent)) 

你不必擔心你的局部變量的名稱將陰影全局(或局部)功能。他們只是在不同的命名空間。

在方案只有一個命名空間,我們必須寫

(define (foo lst) (list 'a lst 'n)) 

Common Lisp中,我們可以這樣寫:

(defun foo (list) (list 'a list 'n)) 

在Common Lisp的,沒有必要寫lst代替list - 因爲本地變量list與全局函數list之間沒有衝突。

訪問其他命名空間

爲了獲取存儲在你可以使用FUNCTION變量的函數對象。

(let ((my-function (function numberp))) 
    (funcall my-function 10)) 

(function foo)可以爲#'foo寫短。

FUNCALL調用函數對象。

OTOH,如果要存儲一個函數對象從函數命名空間的變量,只有一個辦法:

(setf (symbol-function 'foo) my-function) 

也是必要的對象是一個真正的函數,而不是別的東西(一個數字,一個字符串......)。否則,你會看到一個錯誤。

這樣做的副作用是Common Lisp從來不需要檢查(foo bar)中的FOO是否真的是一個函數。它不可能是一個函數或未定義的函數。

0

Scheme(一種Lisp方言,可以這麼說)和Common Lisp之間的差異之一是在Scheme中,變量和函數有一個名稱空間,而在CL中有兩個獨立的名稱空間。 因此,在Scheme中,「define」設置了這個唯一的name-to-value assoc,而在CL中,該值爲「define」,函數關聯爲「defun」。

所以,在CL您可以:

(define foo ...something...) 
(defun foo ...somethingElse...) 

混淆讀者。

在流程中,只有一個:

(define foo something) 

如果這是好還是壞已經在過去的近乎宗教爭端。

+0

Common Lisp沒有「DEFINE」。 –

+0

是的,你是對的;應該寫下「defvar」,並提到它只定義全局變量。 – blabla999