2012-09-13 181 views
1

我想分支並學習lisp。其中一個基本要素就是實現一個簡單的堆棧。一切正常,但我的pop功能。堆棧彈出不返回

;Returns and removes the first element of the stack 
(defun my-pop() 
    (let (temp (car *stack*)) 
    (setq *stack* (cdr *stack*)) 
    temp)) 

這正確地刪除堆棧的「頂部」,但不返回它。此前,我有這樣的:

;Returns and removes the first element of the stack 
(defun my-pop() 
    (print (car *stack*) 
    (setq *stack* (cdr *stack*))) 

但我寧願返回頂部。

我在做什麼錯? (我認爲這與範圍有關...)

+0

需要注意的是,標準中已經定義了'pop'和'push'。 – Svante

+0

@Svante還應該注意的是,問題始於「我試圖分支並學習lisp。其中一個基本原理就是實現一個簡單的堆棧。」 (這就是爲什麼它被命名爲'我的流行') – SomeKittens

+0

這就是爲什麼我說「應該注意」,而不是「閱讀精美的手冊」。我不希望人們搜索「stack common lisp」,然後認爲他們必須自己實現它。 – Svante

回答

3

與範圍無關,這是一個語法問題。 LET的語法是:

(let ((var1 val1) 
     (var2 val2) 
     ...) 
    body) 

另外,(varN valN)有時簡稱爲只是varN,這相當於(varN nil)。所以你寫的是等價於:

(let ((temp nil)  ; bind TEMP to NIL 
     (car *stack*)) ; bind CAR to value of *STACK* 
    (setq *stack* (cdr *stack*)) 
    temp) 

您需要在您的LET-綁定一個額外的括號:

(let ((temp (car *stack*))) 
    (setq *stack* (cdr *stack*)) 
    temp) 

您還可以使用內置的操作PROG1:

(prog1 
    (car *stack*) 
    (setq *stack* (cdr *stack))) 
+0

太棒了。你有'prog1'的細節鏈接嗎? (我很難找到一個好的文檔來源) – SomeKittens

+0

Common Lisp Hyperspec:http://www.lispworks.com/documentation/HyperSpec/Front/index.htm – Barmar

+0

謝謝!當我回到宿舍時,我會檢查一下,然後接受它。 – SomeKittens