Я решил, что приведу в порядок следующую функцию.Идея в том, что он использует cond
, но также содержит if
s, что затрудняет когнитивную обработку.Это bst код из книги ansi common lisp.
(defun percolate (bst)
(cond ((null (node-l bst))
(if (null (node-r bst))
nil
(rperc bst)))
((null (node-r bst)) (lperc bst))
(t (if (zerop (random 2))
(lperc bst)
(rperc bst)))))
Моя идея заключалась в том, чтобы удалить if, добавив больше случаев в cond
, а затем обосновать все это с помощью причины слева,эффект справа.Вот что я придумал:
(defun percolate (bst) ; [6,7,7a]
(cond (((and (null (node-l bst)) (null (node-r bst))) nil)
((null (node-l bst)) (rperc bst))
((null (node-r bst)) (lperc bst))
(t (if (zerop (random 2))
(lperc bst)
(rperc bst))))))
Однако, это приводит к ошибке
*** - SYSTEM::%EXPAND-FORM: (AND (NULL (NODE-L BST)) (NULL (NODE-R BST))) should be a
lambda expression
Я могу найти другие сообщения об этой проблеме при переполнении стека, например здесь но я до сих пор не понимаю этого.Является ли cond отклонением от нормального синтаксиса lisp?Я хотел бы указать на мое предположение, которое ошибочно.
Для записи интерпретатор принимает следующий код, но, очевидно, мы не хотим его так писать.
(defun percolate (bst) ; [6,7,7a]
(let ((both-null (and (null (node-l bst)) (null (node-r bst))))
(l-null (null (node-l bst)))
(r-null (null (node-r bst))))
(cond ((both-null nil)
(l-null (rperc bst))
(r-null (lperc bst))
(t (if (zerop (random 2))
(lperc bst)
(rperc bst)))))))