LISP列表不附加和打印两次

时间:2017-09-10 16:55:38

标签: append lisp

我对LISP很新,我正在努力研究课堂上的cond声明。目前,我正在尝试检查传递的值是否为列表,如果是,请将字母d附加到列表中。

这是我的代码:

(defun test(L)
(listp L)
(cond ((listp L) (append L (list 'd)))
)
(write L)
)
(test (list 'a 'b 'c))

我得到的输出是:

(A B C)

(A B C)

如果我将测试更改为:(test (car(list 'a 'b 'c)))

我得到的新输出是:

A

A

我想知道的两件事是

1。)如果第一个测试通过列表,为什么D不会附加到列表中?

2。)为什么要打印两次?我正在使用LISP Works,所以我认为它实际上是它总是输出最终值的东西。

1 个答案:

答案 0 :(得分:3)

1。)同样的原因str + "d"不会在Java或Python中改变str。它会创建一个您不使用的新列表!

>>> str + "d"
'abcd'
>>> str
'abc'

疯狂的相似不是吗?

2.)在CL中,return是最后一次计算的表达式。 REPL将每个顶级表达式结果打印到终端。 Python也是这样做的:

>>> def test():
...  x = 2 + 3
...  print x
...  return x
... 
>>> test()
5
5

更新

如何改变参数列表。简单的答案是你需要改变最后一对参数:

(defun test (l)
  (assert (consp 1) (l) "l needs to be a non nil list. Got: ~a" l)
  (nconc l (list 'd)
  (write l)))

(defparameter *test1* (list 1 2 3))
(defparameter *test1-copy* *test1*)
(test *test1*)            ; ==> (1 2 3 d) (and prints (1 2 3 d))
*test1*                   ; ==> (1 2 3 d)
*test1-copy*              ; ==> (1 2 3 d)
(eq *test1* *test1-copy*) ; ==> t

(test '())
** error l needs to be a non nil list. Got: NIL

(nconc l x)执行(setf (cdr (last l)) x)

如果你需要改变绑定,那么你需要制作一个宏:

(defmacro testm (var)
  (assert (symbolp var) (var) "List needs to be a variable binding. Got: ~a" var)
  `(progn
     (when (listp ,var)
       (setf ,var (append ,var (list 'd)))
     (write ,var))))

(macroexpand '(testm *test2*))
; ==> (progn 
;       (when (consp *test2*)
;         (setf *test2* (append *test2* (list 'd))))
;       (write *test2*))

(defparameter *test2* (list 1 2 3))
(defparameter *test2-copy* *test2*)
(testm *test2*)           ; ==> (1 2 3 d) (and prints (1 2 3 d))
*test2*                   ; ==> (1 2 3 d)
*test2-copy*              ; ==> (1 2 3)
(eq *test2* *test2-copy*) ; ==> nil

(defparameter *x* nil)
(testm *x*)               ; ==> (d) (and prints (d))
*x*                       ; ==> (d)

(testm '(1))
** error List needs to be a variable binding. Got: '(1)

习惯性的方式

(defun test (list)
  (if (consp list)
      (append list '(d))
      list))

(write (test '(1 2 3)))
; ==> (1 2 3 d) (and prints (1 2 3 d))  

(defparameter *test3* '(1 2 3))
(setf *test3* (test *test3*))
*test3* ; ==> (1 2 3 d)