В коде есть несколько проблем. Во-первых, у вас есть несколько дополнительных круглых скобок. e1
означает значение e1
, но (e1)
означает возвращаемое значение функции e1
. Поскольку у вас нет такой функции, она потерпит неудачу.
Кроме того, в вашей петле не хватает условия завершения. Как и сейчас, с первым исправленным выпуском он будет работать бесконечно, всегда беря вторую ветвь и рекурсивно называя себя nil
как L
.
И, наконец, первый аргумент cons
в последнем отделении не так: Когда (car L)
не соответствует e1
, вы хотите построить результат от (car L)
и не e1
, верно? Это сохранение того, что было в списке, и не заменять его первым аргументом.
Вот фиксированная версия:
(defun my-replace (e1 e2 L)
(cond
;;if at the end of list, terminate
((null L) nil)
;;if the first of L is e1, cons e2 & rest L
((equal (car L) e1)
(cons e2 (my-replace e1 e2 (cdr L))))
;;else cons e1 & rest L
(t
(cons (car L) (my-replace e1 e2 (cdr L))))))