在列表中,如何通过将列表作为参数的函数对列表进行修改?

时间:2013-02-06 00:59:35

标签: list lisp common-lisp pass-by-value

我在Lisp中编写了一个程序,将两个列表中的公共元素放入一个新列表中。这是我的代码。

(defun test (a b)
  (let ((alist nil) (blist nil))
    (progn
      (join a b alist blist)
      (print blist))))

(defun join (a b alist blist)
  (cond
   ((and (null a) (null b))
    (setf blist (cons alist blist)))
   ((equal (car a) (car b))
    (setf alist (cons (list (car a) (car b)) alist)))
   (t (join (cdr a) (cdr b) alist blist))))

但该函数的输出始终为nil。然后我在互联网上查找了一些东西,发现当我尝试使用setf时,它不再指向原始列表,而是指向一个新列表。所以,如果我不能使用setf,我还可以用什么来实现它呢?

2 个答案:

答案 0 :(得分:1)

(defun test (a b)
  (let ((alist nil) (blist nil))   ; two variables initialized to NIL
    (progn                         ; this PROGN is not needed
      (join a b alist blist)       ; you call a function, but ignore the
                                   ; return value? Why?
      (print blist))))             ; since blist was never modified, this
                                   ; can only be the initial value, NIL



(defun join (a b alist blist)      ; four new local variables
  (cond
   ((and (null a) (null b))
    (setf blist (cons alist blist)))    ; why do you set the variable BLIST?
                                        ; you never use it later

   ((equal (car a) (car b))
    (setf alist (cons (list (car a) (car b)) alist)))
                                        ; why do you set the variable ALIST?
                                        ; you never use it later

   (t (join (cdr a) (cdr b) alist blist))))
                                        ; the only recursive call of JOIN

您只能更改词汇可达的变量。

答案 1 :(得分:1)

不要使用"输出" Lisp中的参数。最好从函数返回结果。 此外,还有一个功能交叉点#39;在CL中你做了你想要的,所以请使用它,除非它是一个练习(然后你可以查看它的实现)。