Вы, конечно, можете изменить глобальные переменные из внутренних функций:
[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 кодеров не закрывают свои скобки, как скобки в языке Алгол стиля:
(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)))))))))
Теперь у нас есть nil
для первой ветви в 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))))))))
Мы также с помощью let
установить некоторые переменные 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))))))))
Ваш код уже включает в себя назначение на '* Vlist *' 'используя setq'. Это '(setq * vlist * (добавить cur-node * vlist *)'. Непонятно, что вы просите. Однако ваш синтаксис неверен. 'If' должен выглядеть как' (if (curp-node) cur-node (progn (setq ...) (bfs-core ...))) '. –