Могут ли функции lisp возвращать ссылки или получать аргументы по ссылке? - PullRequest
4 голосов
/ 13 апреля 2011

Я хочу знать, как это работает:

(setf (car x) 42)

Возвращает ли (car x) назначаемую ссылку на setf? Или все это просто макромагия? Как работает setf или машина?

Я знаю, что передача по ссылке была бы ужасным грехом в функциональном программировании, но я хочу знать, как это делается.

Ответы [ 2 ]

9 голосов
/ 13 апреля 2011

Это макро-магия.Форма (setf place value) - не что иное, как специализированное расширение макроса.Например, (setf (car x) 42) можно перевести как-то так: (rplaca x 42).

Вы можете увидеть, как ваша реализация на Лиспе расширяет форму SETF с помощью MACROEXPAND, вот так (мой примериспользует SBCL, другие реализации могут иметь совершенно разные расширения):

CL-USER> (macroexpand '(setf (aref foo 10) 1234))
(SB-KERNEL:%ASET FOO 10 1234)
T

Вы также можете определить свои собственные расширения:

CL-USER> (defvar *value* 0)
*VALUE*
CL-USER> (defun get-value () *value*)
GET-VALUE
CL-USER> (defun (setf get-value) (x) (setq *value* x))
(SETF GET-VALUE)
CL-USER> (setf (get-value) 42)
42
CL-USER> (get-value)
42
CL-USER> (macroexpand '(setf (get-value) 23))
(LET* ()
  (MULTIPLE-VALUE-BIND (#:NEW1058) 23 (FUNCALL #'(SETF GET-VALUE) #:NEW1058)))
T
6 голосов
/ 13 апреля 2011

В Common Lisp это место .Место - это форма, для которой определитель setf определен.Это что-то вроде обобщенного справочника.

Для более подробного рассмотрения смотрите Hyperspec .

...