SETF - это макрос.
Идея состоит в том, что установка и чтение элементов из структур данных - это две операции, но обычно требуется два разных имени (или, может быть, даже что-то более сложное).SETF теперь позволяет использовать только одно имя для обоих:
(get-something x)
Выше считывается структура данных.Тогда обратное просто:
(setf (get-something x) :foobar)
Приведенный выше устанавливает структуру данных в X с помощью: FOOBAR.
SETF не рассматривает (получить что-то x) как ссылку или что-то в этом роде.Он просто имеет базу данных обратных операций для каждой операции.Если вы используете GET-SOMETHING, он знает, что такое обратная операция.
Откуда это знает SETF?Просто: вы должны сказать это.
Для операции NTH, SETF знает, как установить n-й элемент.Это встроено в Common Lisp.
Для вашей собственной операции GET-Y в SETF такой информации нет.Вы должны сказать это.Посмотрите Common Lisp HyperSpec для примеров.Одним из примеров является использование DEFUN и (SETF GET-Y) в качестве имени функции.
Также обратите внимание на следующие проблемы стиля в вашем примере:
lst не подходитимя для переменной DEFVAR.Используйте * list * в качестве имени, чтобы прояснить, что это специальная переменная, объявленная DEFVAR (или аналогичной ей).
'(1 2) - литеральная константа.Если вы пишете программу Common Lisp, последствия ее изменения не определены.Если вы хотите изменить список позже, вам следует добавить его в LIST или что-то вроде COPY-LIST.