您当然可以从内部函数更改全局变量:
[1]> (defparameter *visited-lists* nil)
*VISITED-LISTS*
[2]> *visited-lists*
NIL
[3]> (defun change-global-value ()
(setf *visited-lists* (append (list 'new-value)
*visited-lists* )))
CHANGE-GLOBAL-VALUE
[4]> *visited-lists*
NIL
[5]> (change-global-value)
(NEW-VALUE)
[6]> *visited-lists*
(NEW-VALUE)
[7]> (change-global-value)
(NEW-VALUE NEW-VALUE)
[8]> *visited-lists*
(NEW-VALUE NEW-VALUE)
但是让我们再看一下您的代码:
(defun bfs-core(node-list)
(let (cur-node tmp-node-list)
(if (null node-list)
NIL
(progn
; (if (= 1 (length node-list))
(setq cur-node (car node-list))
(setq tmp-node-list (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))
)
)
)
首先,让我们在正确的行上加上右括号,并删除注释掉的代码。大多数 Lisp 编码器不会像 ALGOL 风格语言中的大括号那样关闭括号:
(defun bfs-core(node-list)
(let (cur-node tmp-node-list)
(if (null node-list)
NIL
(progn
(setq cur-node (car node-list))
(setq tmp-node-list (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node)))))))))
现在,我们有了 anil
的第一个分支if
。我们可以将其更改为unless
具有内置的progn
,因此我们也不需要它:
(defun bfs-core(node-list)
(let (cur-node tmp-node-list)
(unless (null node-list) ;;changed this line to an unless, dropped nil, progn
(setq cur-node (car node-list))
(setq tmp-node-list (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))))
我们还使用 alet
将一些变量设置为nil
,当我们进入 时unless
,我们立即将变量设置为我们实际想要使用的值。让我们切换它,以便我们只在要使用它们时创建变量:
(defun bfs-core(node-list)
(unless (null node-list) ;;switched this line and the let below
(let ((cur-node (car node-list)) ;;also set the variables inside the let
(tmp-node-list) (cdr node-list))
(if (goalp cur-node)
cur-node
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))))
好的,我们已经有了更清晰的代码。耶!
让我们看一下这里的调用之一:
((setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))
你的意思是把它作为一个电话,而不是两个?这和这个有区别:
((setq *vlist* (append cur-node *vlist*)))
(bfs-core (append tmp-node-list (expand cur-node)))
你看得到差别吗?第一个是单个语句;第二个是两个。你可能想要第二个,因为你想改变*vlist*
,然后打电话bfs-core
。而且,要做到这一点,你需要progn
:
(defun bfs-core(node-list)
(unless (null node-list)
(let ((cur-node (car node-list))
(tmp-node-list) (cdr node-list))
(if (goalp cur-node)
cur-node
(progn (setq *vlist* (append cur-node *vlist*))
(bfs-core (append tmp-node-list (expand cur-node))))))))