我是一个完整的Lisp n00b,所以请保持温柔.
我无法理解CL关于[un-]声明的自由变量的想法.我认为:
(defun test ()
(setq foo 17)
)
Run Code Online (Sandbox Code Playgroud)
将定义一个声明变量foo并将其设置为17的函数.但是,我得到了
;Compiler warnings :
; In TEST: Undeclared free variable FOO
Run Code Online (Sandbox Code Playgroud)
我的实际案例有点大; 我的代码(代码段)看起来像这样:
(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]
)
Run Code Online (Sandbox Code Playgroud)
这给了我:
;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 =
Run Code Online (Sandbox Code Playgroud)
是的,是的,我意识到我正在使用太多的中间变量,但是我试图理解在我过于喜欢将所有内容压缩到最小类型字符之前发生了什么,这在CL世界中很流行.
所以,无论如何......有人可以解释以下内容:
(...)围绕setq声明吗?!(也就是说,我希望var对于从(... (setq ...) ...)parens 1级以外的所有内容都有效并且范围有限setq,不是吗?注意:我非常擅长使用C,Java,Javascript,Obj-C和相关的过程语言.我觉得功能编程是不同的.现在,我只是在咀嚼语法.
谢谢!
PS如果重要,defun p8是在文本文件(TextMate)中,我正在运行它Clozure CL.但是,希望这一切都不重要!
在lisp中,变量可以使用defparameter或声明defvar.
(defparameter var1 5)
(defvar var2 42)
Run Code Online (Sandbox Code Playgroud)
这导致全局(动态)变量.
defvar和之间的区别defparameter是defvar不重新初始化已存在的变量.
引入局部(词汇)变量,例如使用let或let*(顺序初始化变量).
未声明的自由变量意味着您已使用(此处setq)变量,而该变量未在其使用的上下文中绑定.然后可以为您声明它,但随后可能作为全局(动态)变量.这样做的结果是,如果在多个函数中使用具有相同名称的未声明变量,则将在所有函数中引用相同的变量.
您的代码可以这样写:
(loop for x from 0 to (- (length str) str-len) do
(let* ((last (+ x str-len)) ; get the last char of substring
(subs (subseq str x last)) ; get the substring
(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))))
Run Code Online (Sandbox Code Playgroud)
使用循环的变量绑定属性,它也可以写成
(loop for x from 0 to (- (length str) str-len)
for last = (+ x str-len)
for subs = (subseq str x last)
for prod = (prod-string subs)
when (> prod max) do
(setq max prod)
(setq max-str subs))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1849 次 |
| 最近记录: |