Recursion 公共Lisp:error";CDR LST应该是一个lambda表达式;

Recursion 公共Lisp:error";CDR LST应该是一个lambda表达式;,recursion,lisp,common-lisp,clisp,Recursion,Lisp,Common Lisp,Clisp,我正在做一个程序,它接受一个列表和两个原子,如果列表中出现原子1,就用原子2替换原子1。 我正在使用Ubuntu系统在文本编辑器中编程 下面是我的代码: #! /usr/bin/clisp (defun my-replace (lst x y) (cond ((eq lst nil) nil) ((eq (cdr lst) nil) nil) ((eq (car lst) x) (setq (car lst) y)) ( t (my-replace ((cd

我正在做一个程序,它接受一个列表和两个原子,如果列表中出现原子1,就用原子2替换原子1。
我正在使用Ubuntu系统在文本编辑器中编程

下面是我的代码:

#! /usr/bin/clisp

(defun my-replace (lst x y)
  (cond
    ((eq lst nil) nil)
    ((eq (cdr lst) nil) nil)
    ((eq (car lst) x) (setq (car lst) y))
    ( t (my-replace ((cdr lst) x y)))))
当我尝试执行此操作时,Clisp显示以下错误:

***-系统::%EXPAND-FORM:(CDR LST)应为lambda表达式

我是Lisp的初学者。
请告诉我如何解决此错误。

编辑: 这个答案指出了代码片段中的另一个明显错误。标题中的错误是由于
(cdr lst)x y
周围有额外的参数,使得它
((cdr lst)x y)
,只有当
(cdr lst)
是lambda表达式并且可以调用时才有意义


通常,如果要将某个内容绑定到某个值,可以使用
set
setq
set
的一个特殊版本,当第一个参数是qutoed值时,因此您不需要编写
(set'horse 123)
,而是编写
(setq horse 123)

但是,您不希望将符号绑定到值,而是希望将列表中的元素转换为值。这是您要使用
setf
的时候

(let ((lst (list 1 2 3)))
  (setf (car lst) 4)
  (princ lst)) ;; (4 2 3)
有关更多信息,请参见优秀答案。

编辑: 这个答案指出了代码片段中的另一个明显错误。标题中的错误是由于
(cdr lst)x y
周围有额外的参数,使得它
((cdr lst)x y)
,只有当
(cdr lst)
是lambda表达式并且可以调用时才有意义


通常,如果要将某个内容绑定到某个值,可以使用
set
setq
set
的一个特殊版本,当第一个参数是qutoed值时,因此您不需要编写
(set'horse 123)
,而是编写
(setq horse 123)

但是,您不希望将符号绑定到值,而是希望将列表中的元素转换为值。这是您要使用
setf
的时候

(let ((lst (list 1 2 3)))
  (setf (car lst) 4)
  (princ lst)) ;; (4 2 3)

有关更多信息,请参阅优秀答案。

首先,您应该改进格式和缩进:

(defun my-replace (lst x y)
  (cond
   ((eq lst nil) nil)
   ((eq (cdr lst) nil) nil)
   ((eq (car lst) x) (setq (car lst) y))
   (t (my-replace ((cdr lst) x y)))))
让我们看看代码:

(defun my-replace (lst x y)
; in Common Lisp you can write LIST instead of LST
; what are x and y? The naming is not very speaking.

  (cond
   ((eq lst nil) nil)

   ((eq (cdr lst) nil) nil)   ; why this clause?

   ((eq (car lst) x) (setq (car lst) y))
   ; instead of SETQ use SETF

   (t (my-replace ((cdr lst) x y)))))
                  ; here is a function call? why the extra parentheses
我将首先集中讨论一个非破坏性的版本。您尝试编写一个破坏性修改列表的版本。不要。创建一个已完成替换的新列表


如果你想写一个破坏性的版本,你可以这样做,但首先要把基本知识做好。

首先你应该改进格式和缩进:

(defun my-replace (lst x y)
  (cond
   ((eq lst nil) nil)
   ((eq (cdr lst) nil) nil)
   ((eq (car lst) x) (setq (car lst) y))
   (t (my-replace ((cdr lst) x y)))))
让我们看看代码:

(defun my-replace (lst x y)
; in Common Lisp you can write LIST instead of LST
; what are x and y? The naming is not very speaking.

  (cond
   ((eq lst nil) nil)

   ((eq (cdr lst) nil) nil)   ; why this clause?

   ((eq (car lst) x) (setq (car lst) y))
   ; instead of SETQ use SETF

   (t (my-replace ((cdr lst) x y)))))
                  ; here is a function call? why the extra parentheses
我将首先集中讨论一个非破坏性的版本。您尝试编写一个破坏性修改列表的版本。不要。创建一个已完成替换的新列表


如果您想编写一个破坏性的版本,您可以这样做,但首先要正确掌握基本知识。

您正在修改一个文字列表。在许多编程语言中,包括CommonLisp,这通常不是一个好主意。使用
LIST
创建一个新的列表,可以毫无问题地进行修改。这都是很好的建议,我知道OP已被接受,但这并不能解释或解决系统问题::%EXPAND-FORM:(CDR LST)应该是一个lambda表达式错误。@JoshuaTaylor当然。不知何故,我把
(cdrlst)
误读为
(carlst)
。我在回答的顶部加了一条注释。编辑是一种改进(因为它提到了实际的错误)。我不确定我是否理解你误读(cdr列表)为(汽车列表);同样的错误会发生在
((汽车列表)…)
((cdr列表)…)
@JoshuaTaylor I上,尽管错误是针对上面的行(使用
setq
)。甚至没有发现额外的参数:PYou正在修改一个文本列表。在许多编程语言中,包括CommonLisp,这通常不是一个好主意。使用
LIST
创建一个新的列表,可以毫无问题地进行修改。这都是很好的建议,我知道OP已被接受,但这并不能解释或解决系统问题::%EXPAND-FORM:(CDR LST)应该是一个lambda表达式错误。@JoshuaTaylor当然。不知何故,我把
(cdrlst)
误读为
(carlst)
。我在回答的顶部加了一条注释。编辑是一种改进(因为它提到了实际的错误)。我不确定我是否理解你误读(cdr列表)为(汽车列表);同样的错误会发生在
((汽车列表)…)
((cdr列表)…)
@JoshuaTaylor I上,尽管错误是针对上面的行(使用
setq
)。甚至没有发现额外的参数:p这可能是一个重复的,或,或,或,或,等,所有这些都有相同的基本问题:
(…)
@JoshuaTaylor:CLISP错误消息也不是很好…这可能是一个重复的,或,或,或,或,或,等关闭。,所有这些都有相同的基本问题:
(…)…)
@JoshuaTaylor:CLISP错误消息也不是很好。。。