Common Lisp:错误 "CDR LST should be a lambda expression"
Common Lisp: error "CDR LST should be a lambda expression"
我正在做一个接受一个列表和两个原子的程序,如果 atom-1 出现在列表中,则将 atom-1 替换为 atom-2。
我正在使用 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 显示此错误:
*** - SYSTEM::%EXPAND-FORM: (CDR LST) should be a lambda expression
我是 Lisp 初学者。
请告诉我如何解决这个错误。
编辑:
这个答案指出了代码片段中的另一个明显错误。标题中的错误是因为 (cdr lst) x y
周围的额外 parens,使其成为 ((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)
有关详细信息,请参阅 this 出色的答案。
首先你应该改进格式和缩进:
(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
我会首先关注一个非破坏性的版本。您尝试编写一个破坏性修改列表的版本。不。创建一个完成替换的新列表。
如果你想写一个破坏性的版本,你可以这样做,但首先要把基础做好。
我正在做一个接受一个列表和两个原子的程序,如果 atom-1 出现在列表中,则将 atom-1 替换为 atom-2。
我正在使用 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 显示此错误:
*** - SYSTEM::%EXPAND-FORM: (CDR LST) should be a lambda expression
我是 Lisp 初学者。
请告诉我如何解决这个错误。
编辑:
这个答案指出了代码片段中的另一个明显错误。标题中的错误是因为 (cdr lst) x y
周围的额外 parens,使其成为 ((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)
有关详细信息,请参阅 this 出色的答案。
首先你应该改进格式和缩进:
(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
我会首先关注一个非破坏性的版本。您尝试编写一个破坏性修改列表的版本。不。创建一个完成替换的新列表。
如果你想写一个破坏性的版本,你可以这样做,但首先要把基础做好。