SETFable против места (CLHS) против места (Norvig)
Это setf
в состоянии так же, как место в CLHS и местоположение в PAIP Norvig?
Я пытаюсь выяснить, что это за место в Common Lisp, но для меня объяснение HyperSpec
место n. 1. форма, которая подходит для использования в качестве обобщенной ссылки. 2. концептуальное местоположение, на которое ссылается такое место [1].
только ограниченная помощь.
(Я знаю, что это не тот вопрос, который подходит SO, но если кто-то знает хорошую статью, которая объясняет setfable/place/location, я был бы признателен за ссылку / ссылку)
1 ответ
Первоначально изменяемая структура данных имеет геттер и сеттер. Пример для car
/rplaca
а также cdr
/rplacd
:
CL-USER 68 > (let ((a (cons 1 2)))
(print (list (car a) (cdr a)))
(rplaca a 'foo)
(rplacd a 'bar)
(print (list (car a) (cdr a)))
(values))
(1 2)
(FOO BAR)
В этом примере получателем являются car
а также cdr
для минусов клетки. Сеттеры rplaca
(заменить автомобиль) и rplacd
(заменить CDR).
Каждая изменяемая структура данных имеет это, и обычно не существует систематического способа угадать имя установщика, зная имя получателя.
Таким образом, идея состояла в том, чтобы иметь реестр получателя и установщика. Зарегистрируйте установщик для получателя, и пользователь должен знать только получатель. setf
макрос (и другие, как incf
, decf
а также определяемые пользователем макросы), затем выполняет поиск метода установки для используемого метода получения.
Пример выше с setf
макрос выглядит так:
CL-USER 69 > (let ((a (cons 1 2)))
(print (list (car a) (cdr a)))
(setf (car a) 'foo)
(setf (cdr a) 'bar)
(print (list (car a) (cdr a)))
(values))
(1 2)
(FOO BAR)
Как вы видите использование rplaca
а также rplacd
был заменен setf
макро.
Таким образом, место в основном является зарегистрированной формой, для которой есть сеттер. Для этого используются defsetf и define-setf- expander.
define-modify-macro используется для определения макроса, который может изменить место.
Например, мы можем определить способ умножения стоимости места, аналогичноincf
(увеличить место) иdecf
(уменьшить место).
Эта функция старая и изначально вместо слова использовалось поле слова. Таким образом, макросы, которые могут использовать место, заканчиваются на f (поле).
CL-USER 71 > (define-modify-macro multf (&rest args)
* "multiply")
MULTF
CL-USER 72 > (let ((a (cons 1 2)))
(print (list (car a) (cdr a)))
(multf (car a) 2)
(multf (cdr a) 4)
(print (list (car a) (cdr a)))
(values))
(1 2)
(2 8)