Короче говоря: вы не можете сделать это, кроме как переписав функцию eval и изменив компилятор вашего Lisp. Правила оценки зафиксированы стандартом Лисп.
Редактировать После прочтения расширенного вопроса, я не думаю, что вы можете достичь полной прозрачности для своих ссылок здесь. В сценарии, подобном
(defclass foo () (reference :accessor ref))
(ref some-foo)
Результатом обращения к ref является просто значение; он не будет рассматриваться для оценки независимо от его типа.
Конечно, вы можете определить свои методы доступа таким образом, чтобы разрешение было прозрачным:
(defmacro defresolver (name class slot)
`(defmethod ,name ((inst ,class))
(fetch-remote-reference (slot-value inst ',slot))))
(defresolver foo-reference foo reference)
Редактировать Вы можете (вроде) подключиться к механизму разрешения символов Common Lisp, используя макросы символов:
(defmacro let-with-resolution (bindings &body body)
`(symbol-macrolet ,(mapcar #'(lambda (form) (list (car form) `(fetch-aux ,(cadr form)))) bindings) ,@body))
(defmethod fetch-aux ((any t)) any)
(defmethod fetch-aux ((any reference)) (fetch-remote-reference any))
Однако теперь все становится довольно загадочным; и переменные уже не переменные, а магические символы, которые просто выглядят как переменные. Например, изменение содержимого переменной «связанный» этим макросом невозможно. Лучшее, что вы можете сделать с этим подходом, - это предоставить расширение setf
для fetch-aux
, которое изменяет исходное место.