Есть ли способ временно импортировать несколько функций из пакета в текущий пакет, используя стандартные функции/макросы common-lisp?
Я не смог найти такой способ и пришлось написать свой собственный. Я бы не хотел ничего кодировать или вводить еще одну языковую конструкцию, если стандарт уже предоставляет такую функциональность.
(defmacro with-functions (functions the-package &body body)
"Allows functions in the-package to be visible only for body.
Does this by creating local lexical function bindings that redirect calls
to functions defined in the-package"
`(labels
,(mapcar (lambda (x) `(,x (&rest args)
(apply (find-symbol ,(format nil "~:@(~a~)" x)
,the-package)
args)))
functions)
,@body))
Пример использования:
(defclass-default test-class ()
((a 5 "doc" )
(b 4 "doc")))
#<STANDARD-CLASS TEST-CLASS>
CL-USER>
(with-functions (class-direct-slots slot-definition-name) 'sb-mop
(with-functions (slot-definition-initform) 'sb-mop
(slot-definition-initform
(car (class-direct-slots (find-class 'test-class))))))
5
CL-USER>
EDIT: Включил в макрос некоторые предложения Райнера.
Я решил сохранить возможность поиска во время выполнения, за счет временных затрат на поиск функции в пакете.
Я пытался написать макрос with-import, который использовал бы shadowing-import и unintern, но не смог заставить его работать. У меня были проблемы с тем, что читатель говорил, что импортированные функции еще не существуют (во время чтения), прежде чем код, который импортировал функции, был оценен.
Я думаю, что лучше заставить его работать с shadowing-import и unintern, так как это будет намного чище, быстрее (хотя и без возможности поиска во время выполнения) и работать с функциями и символами в пакетах.
Мне было бы очень интересно посмотреть, сможет ли кто-нибудь создать макрос with-import, используя unintern и shadowing-import.