Common Lisp:错误"CDR LST应该是lambda表达式"

oja*_*jas 1 lisp recursion clisp common-lisp

我正在做一个接受一个列表和两个原子的程序,如果atom-1出现在列表中,则用atom-2替换atom-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)))))
Run Code Online (Sandbox Code Playgroud)

当我尝试执行此操作时,Clisp显示以下错误:

*** - SYSTEM::%EXPAND-FORM: (CDR LST) should be a lambda expression

我是Lisp的初学者.
请告诉我如何解决这个错误.

Rai*_*wig 8

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

(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)))))
Run Code Online (Sandbox Code Playgroud)

我们来看看代码:

(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
Run Code Online (Sandbox Code Playgroud)

我会首先关注一个非破坏性的版本.您尝试编写破坏性修改列表的版本.别.创建一个完成替换的新列表.

如果你想编写破坏性版本,你可以这样做,但首先要掌握基础知识.