有詞法作用域的變量叫詞法變量(lexical variable)。
在詞法作用域下,一個符号參照到語境中符号名字出現的地方(可以了解為參照到定義)。局部變量預設有着詞法作用域。
eg:
CL-USER> (let ((x 50))
(defun foo ()
x))
FOO
CL-USER> (foo)
50
CL-USER> (let ((x 80))
(foo))
;Compiler warnings :
; In an anonymous lambda form: Unused lexical variable X
50
有動态作用域的變量叫特别變量(special variable)。
(PS.special宣告是獨一無二的,因為它可以改變程式的行為。所有其它的宣告隻是給編譯器的建議;他們或許可以讓一個程式運作得更快,但他們不會改變程式的行為。)
而動态作用域,我們在環境中函數被調用的地方尋找一個變量(可以了解為參照到調用)。全局變量有着動态作用域。
要使一個變量是動态作用域的,我們需要在任何它出現的語境中宣告它是special,如:
CL-USER> (let ((z 12))
(defun foo ()
(declare (special z))
z))
;Compiler warnings :
; In an anonymous lambda form: Unused lexical variable Z
FOO
CL-USER> (let ((z 19))
(declare (special z))
(foo))
當然全局變量就不需要顯著來說明了:
CL-USER> (progn
(setf r 99)
(defun foo ()
r))
;Compiler warnings :
; In FOO: Undeclared free variable R
FOO
CL-USER> (foo)
99
CL-USER> (setf r 95)
95
CL-USER> (foo)
95
CL-USER> (let ((r 89))
(foo))
;Compiler warnings :
; In an anonymous lambda form: Unused lexical variable R
95
CL-USER> (let ((r 89))
(declare (special r))
(foo))
89
CL-USER> (progn
(setf r 66)
(foo))
66
轉載于:https://www.cnblogs.com/flowjacky/archive/2012/12/26/2834803.html