Is there a way to temporarily import a few functions from a package into the current package, using standard common-lisp functions/macros?
I couldn't find one and had to roll my own. I'd rather not have to code anything up, or introduce another language construct, if the standard already provides such functionality.
(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))
Example usage:
(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 some of Rainer's suggestions to the macro.
I decided to keep the run-time lookup capability, at the time cost of the run-time lookup to find the function in the package.
I tried to write a with-import macro that used shadowing-import and unintern, but I couldn't get it to work. I had issues with the reader saying that the imported functions didn't exist yet (at read time) before the code that imported the functions was evaluated.
I think getting it to work with shadowing-import and unintern is a better way to go, as this would be much cleaner, faster (no run-time lookup capability though) and work with functions and symbols in packages.
I would be very interested to see if someone can code up a with-import macro using unintern and shadowing-import.