2013-09-28 3 views
1

Я новичок в области шепелявость ... я пишу код, чтобы решить загадку 8 в BFS ...LISP Изменение глобального значения переменной в локальной функции

Я хочу сохранить посещаемый списки в глобальном списке и регулярно меняют свое значение из функции ...

(defparameter *vlist* nil) 
(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)))))) 
        ) 
       ) 
      ) 

defparameter одна моя глобальная переменная ... и witjin функции я хочу, чтобы изменить его значение с SETQ ... я также использовали defvar, setf, set и все возможные комбинации ..... Может ли кто-нибудь помочь мне?

+0

Ваш код уже включает в себя назначение на '* Vlist *' 'используя setq'. Это '(setq * vlist * (добавить cur-node * vlist *)'. Непонятно, что вы просите. Однако ваш синтаксис неверен. 'If' должен выглядеть как' (if (curp-node) cur-node (progn (setq ...) (bfs-core ...))) '. –

ответ

1

Вы, конечно, можете изменить глобальные переменные из внутренних функций:

[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)))))))) 
1

Вот ваш код (переформатирован для стандартного Lisp стиля):

(defparameter *vlist* nil) 
(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))))))))) 

Ваш код, как один ясный проблема.

Форма ((setq *vlist* ...) (bfs-core ...)) в конечном итоге является вызовом функции. Когда у вас есть форма, такая как (exp1 exp2 exp3), тогда exp1 - это функция, применяемая к значениям параметров exp2 и exp3.Ваш exp1 - (setq *vlist* ...), который не оценивает функцию и, конечно же, вы этого не хотели.

переписанной версии кода, что по крайней мере было бы удалить вызов неуместны функцию, является:

(defparameter *vlist* nil) 
(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 
       (progn 
       (setq *vlist* (append cur-node *vlist*)) 
       (bfs-core (append tmp-node-list (expand cur-node))))))))) 
Смежные вопросы