我是一个完全不懂Lisp的新手,请温柔一点。
我对CL中未声明或已声明的自由变量的概念感到困惑。 我认为:
(defun test ()
(setq foo 17)
)
我会定义一个函数,声明一个名为foo的变量并将其设置为17。但是,实际上出现了下列错误:
;Compiler warnings :
; In TEST: Undeclared free variable FOO
我的实际例子比较大;我的代码(片段)看起来像这样:
(defun p8 ()
;;; [some other stuff, snip]
(loop for x from 0 to (- (length str) str-len) do
(setq last (+ x str-len)) ; get the last char of substring
(setq subs (subseq str x last)) ; get the substring
(setq prod (prod-string subs)) ; get the product of that substring
(if (> prod max) ; if it's bigger than current max, save it
(setq max prod)
(setq max-str subs)
)
)
;;; [More stuff, snip]
)
这给了我:
;Compiler warnings for "/path/to/Lisp/projectEuler/p6-10.lisp":
; In P8: Undeclared free variable LAST (2 references)
;Compiler warnings for "/Volumes/TwoBig/AllYourBits-Olie/WasOnDownBelowTheOcean/zIncoming/Lisp/projectEuler/p6-10.lisp" :
; In P8: Undeclared free variable PROD (3 references)
;Compiler warnings for "/Volumes/TwoBig/AllYourBits-Olie/WasOnDownBelowTheOcean/zIncoming/Lisp/projectEuler/p6-10.lisp" :
; In P8: Undeclared free variable SUBS (3 references)
;Compiler warnings for "/Volumes/TwoBig/AllYourBits-Olie/WasOnDownBelowTheOcean/zIncoming/Lisp/projectEuler/p6-10.lisp" :
; In P8: Undeclared free variable =
是的,我知道我使用了太多的中间变量,但我想在将所有内容压缩到最小的输入字符之前,先理解正在发生的事情,这似乎在CL世界中很流行。
所以,无论如何...有人能解释一下以下内容吗:
- Lisp在什么条件下会“声明”一个变量?
- 所述变量的范围是否超出封闭的
(...)
setq
语句周围?!(也就是说,我希望从(... (setq ...) ...)
var对于括号级别有效且范围为setq
外部1级的所有内容,不是吗? - 我是否误解了“未声明的自由变量”消息?
- 您还有其他提示可以帮助我更好地理解正在发生的事情。
注意:我对C、Java、Javascript、Obj-C和相关的过程式语言非常熟悉。我知道函数式编程很不同。现在,我只是在与语法斗争。
谢谢!
P.S. 如果有关系,defun p8
在文本文件(TextMate)中,并且我正在Clozure CL
上运行它。希望这些都不重要!