Мы использовали Lisp в моем курсе искусственного интеллекта. Задания, которые я получил, включали поиск и создание древовидных структур. Для каждого задания я написал что-то вроде:
(defun initial-state ()
(list
0 ; score
nil ; children
0 ; value
0)) ; something else
и построение моих функций вокруг этих «состояний», которые на самом деле представляют собой просто вложенные списки с некоторой слабо определенной структурой.
Чтобы сделать структуру более жесткой, я попытался написать аксессоры, такие как:
(defun state-score ( state )
(nth 2 state))
Это работает для чтения значения (что должно быть всем, что мне нужно сделать в хорошо функциональном мире. Однако, когда время поджимает, и я начинаю безумно взламывать, иногда мне нужна изменяемая структура). Кажется, я не могу SETF вернуть... вещь (место? Значение? Указатель?).
Я получаю ошибку с чем-то вроде:
(setf (state-score *state*) 10)
Иногда мне кажется, что мне повезло написать аксессор/мутатор в виде макроса:
(defmacro state-score ( state )
`(nth 2 ,state))
Однако я не знаю, почему это должен быть макрос, поэтому я, конечно, не должен писать его как макрос (за исключением того, что иногда это работает. Программирование по совпадению - это плохо).
Какова подходящая стратегия для создания таких структур?
Что еще более важно, где я могу узнать о том, что здесь происходит (какие операции и каким образом влияют на память)?