C'è un modo per importare temporaneamente alcune funzioni da un pacchetto nel pacchetto corrente, utilizzando le funzioni/macro standard common-lisp?Common Lisp: metodo migliore per importare temporaneamente alcune funzioni da un pacchetto
Non riuscivo a trovarne uno e ho dovuto rotolare da solo. Preferirei non dover codificare nulla o introdurre un altro costrutto linguistico, se lo standard fornisce già tale funzionalità.
(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))
Esempio utilizzo:
(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: Incorporated alcuni dei suggerimenti di Rainer alla macro.
Ho deciso di mantenere la capacità di ricerca in fase di esecuzione, al momento del costo della ricerca in fase di esecuzione per trovare la funzione nel pacchetto.
Ho provato a scrivere una macro con importazione che utilizzava shadowing-import e unintern, ma non riuscivo a farlo funzionare. Ho avuto problemi con il lettore che diceva che le funzioni importate non esistevano ancora (al momento della lettura) prima che il codice che importava le funzioni fosse valutato.
Penso che farlo funzionare con shadowing-import e unintern sia un modo migliore per andare, in quanto ciò sarebbe molto più pulito, veloce (senza alcuna capacità di ricerca in fase di esecuzione) e funzionerà con funzioni e simboli nei pacchetti.
Sarei molto interessato a vedere se qualcuno può codificare una macro con importazione utilizzando unintern e shadowing-import.
Questo non funziona con le funzioni lessicali, poiché APPLY non può chiamarle usando simboli come nomi. –
Non penso sia possibile con una macro, perché i simboli vengono risolti dal lettore prima che la macro venga espansa, ma potrei sbagliarmi non capisco ancora completamente come funziona il lettore. – Daimrod
@Daimrod Dovrebbe essere possibile costruire una tale macro, ma è molto difficile (e, probabilmente, non importabile), perché dovrai gestire i conflitti di nome, derivanti dalla strategia di risoluzione dei simboli. –