2013-09-28 24 views
1

我在口齒不清領域的新手改變一個全局變量的值...我寫代碼來解決BFS 8拼圖......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 *(append cur-node * vlist *)'。不清楚你在問什麼,但是你的語法不對。'if'應該看起來像'(if(goalp cur-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的程序員不收他們的括號像括號中的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))))))))) 

現在,我們有一個nilif的第一家分店。我們可以將其更改爲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是應用於參數值exp2exp3的函數。你的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)))))))))