Discussion of Common Lisp
-
churib
- Posts: 6
- Joined: Tue Feb 08, 2011 10:22 am
Post
by churib » Mon Mar 21, 2011 4:26 am
Hi!
I am trying to write a macro, which dynamically binds the current package:
Code: Select all
(defmacro with-in-package (package-designator &body body)
`(let ((*package* (find-package ,package-designator)))
,@body))
which expands like this:
Code: Select all
(macroexpand-1 '(with-in-package :sb-cltl2 (variable-information '*package*)))
(LET ((*PACKAGE* (FIND-PACKAGE :SB-CLTL2)))
(VARIABLE-INFORMATION '*PACKAGE*))
but evaluating it gives me an error [SBCL]:
Code: Select all
(with-in-package :sb-cltl2 (variable-information '*package*))
->The function VARIABLE-INFORMATION is undefined.
but this works:
Code: Select all
(sb-cltl2:variable-information '*package*)
:SPECIAL
NIL
((TYPE . PACKAGE))
The macro IN-PACKAGE does nothing else than setting the value of *PACKAGE* (
http://www.lispworks.com/documentation/ ... in_pkg.htm).
What do I miss?
-
pjstirling
- Posts: 166
- Joined: Sun Nov 28, 2010 4:21 pm
Post
by pjstirling » Mon Mar 21, 2011 6:06 am
COMMON-LISP:*PACKAGE* is used by the reader to pick the package to intern unknown symbols as they are read. What is happening is that the form (WITH-IN-PACKAGE :SB_CLTL2 (VARIABLE-INFORMATION '*PACKAGE*) is read, VARIABLE-INFORMATION is interned in whatever package you had to start (probably CL-USER) and then it attempts to execute it. Since the symbol VARIABLE-INFORMATION is not the one from SB-CLTL2, it isn't FBOUNDP, and so you get an error.
You need a reader macro to change the value of *PACKAGE* mid-form.
If you were only to use symbols from packages that are imported by both *PACKAGE* and whichever package you are trying to temporarily bind, then *PACKAGE* probably be whatever you set it to, it just wouldn't be doing what you want (unless you are also calling READ in the body).
-
churib
- Posts: 6
- Joined: Tue Feb 08, 2011 10:22 am
Post
by churib » Mon Mar 21, 2011 7:04 am
Wow - your answer is eye-opening for me! Thanks!