Кадр списка, включающего ассоциированную функцию
Я посмотрел вокруг в сети и не могу найти ответ на свой запрос. Я был бы очень признателен, если бы кто-то смог дать хороший ответ без оценки рейтинга этого поста.
В Лиспе car
, cdr
используются в режиме данных, как '(whatever here)
что имеет смысл для меня.
Теперь в книге Land of Lisp автор объясняет, как создать текстовый движок, и внезапно он использует следующее описание для создания функции.
(defun describe-location (location nodes)
(cadr (assoc location nodes)))
Могу я спросить, почему он делает кадры в списке и почему он дает ответ, а не ошибку? не должен ли это быть режим данных, то есть с кавычкой перед открывающей скобкой '(whatever here)
?
а также почему он использует асс, как в (assoc location nodes)
и не (assoc 'garden *nodes*)
Разве это не второй правильный способ использования assoc
? Я, возможно, скучаю по общей картине, и поэтому буду очень признателен, если кто-то объяснит эти ключевые моменты, пожалуйста.
Большое спасибо!
2 ответа
Я помню книгу, очень весело.
assoc
просто возвращает минусы, автомобиль которых равен заданному значению. Это как find
функция с параметром :key #'car
, Так, например:
CL-USER> (assoc 'a '((a "letter a") (b "letter b") (c "letter c")))
(A "letter a")
поэтому, поскольку мы получаем здесь все минусы, автомобиль которых удовлетворяет критерию, мы можем далее применять cadr
для этого минусы и получить соответствующее значение:
CL-USER> (cadr (assoc 'a '((a "letter a") (b "letter b") (c "letter c"))))
"letter a"
Это все для исполняемого кода. В режиме данных вы просто получаете списки, а не формы, поэтому они не будут выполнены, попробуйте сами:
CL-USER> '(car '(a "letter a"))
(CAR '(A "letter a"))
Режим данных позволяет хранить списки как данные, не пытаясь их выполнить. Поэтому автор использует режим данных для определения описаний комнат в игре, но в функции нам нужно выполнить формы, чтобы получить результат.
Что касается второй части вашего вопроса, это все равно просто авторский дизайн. Конечно можно поставить
(assoc 'garden *nodes*)
но это будет иметь тот же эффект и работать только для расположения в саду.
ASSOC
это функция. Lisp оценивает все свои аргументы и затем вызывает их с этими значениями. Так работает оценка функций в Лиспе.
(assoc 'garden *nodes*)
- Лисп видит это
assoc
это функция. Теперь оценим аргументы. - Лисп оценивает
'garden
к символуgarden
, - Лисп оценивает
*nodes*
к значению переменной*nodes*
, - Лисп звонит
assoc
с этими ценностями.
Сейчас:
(assoc location *nodes*)
- Лисп видит это
assoc
это функция. Теперь оценим аргументы. - Лисп оценивает
location
к значению переменнойlocation
, - Лисп оценивает
*nodes*
к значению переменной*nodes*
, - Лисп звонит
assoc
с этими ценностями.
Если, например, значение переменной location
это символ garden
тогда выше assoc
выражения возвращают тот же результат.