[Openmcl-devel] with-package
Pascal J. Bourguignon
pjb at informatimago.com
Sat Jan 12 06:12:40 PST 2013
Taoufik Dachraoui <dachraoui.taoufik at gmail.com> writes:
> On Sat, Jan 12, 2013 at 2:36 PM, Pascal J. Bourguignon <
> pjb at informatimago.com> wrote:
>
> Taoufik Dachraoui <dachraoui.taoufik at gmail.com> writes:
>
> > Hi
> >
> > I am trying to define a macro as follows:
> >
> > (defmacro with-package ((&rest names) &body body)
> > `(progn
> > (use , at names)
> > , at body
> > (unuse ,@(reverse names))))
> >
> > The issue is that the body may use symbols defined in one of
> > the names (packages) and not in the current package
>
> "Current" WHEN?
>
>
>
> > How to do this? I tried with eval-when but I do not know how to
> use
> > it correctly
>
> What are the situations available to eval-WHEN?
>
> Current package when you call with-package
Ok. When you call with-package, it's at run-time. And at run-time you
can use the current package bound to *package* without any difficulty.
With:
(defun use* (syms) (format t "I'll use ~S~%" syms))
(defun unuse* (syms) (format t "I unused ~S~%" syms))
(defmacro use (&rest syms) `(use* ',syms))
(defmacro unuse (&rest syms) `(unuse* ',syms))
(defmacro with-package ((&rest names) &body body)
`(progn
(use , at names)
, at body
(unuse ,@(reverse names))))
(defpackage :p1 (:export :*v*))
(defparameter p1:*v* 42)
we get:
cl-user> (let ((*package* (find-package :p1)))
(with-package (a b)
(let ((s (find-symbol "*V*" *package*)))
(print (list s (symbol-value s)))
(terpri))))
I'll use (common-lisp-user::a common-lisp-user::b)
(*v* 42)
I unused (common-lisp-user::b common-lisp-user::a)
nil
As you can see, at run-time, find-symbol found the symbol P1:*V* in the
current package that was the package named "P1", and print even printed
it as *v*, since CL:*PACKAGE* was bound to that package named "P1" (and
I have CL:*PRINT-CASE* set to :DOWNCASE).
> ? *package*
> #<Package "COMMON-LISP-USER">
>
> ;; The curent package is COMMON-LISP-USER
>
> ? (with-package (calculus) (share '(fn x (+ x 1))))
> ;;; (share '(fn x (+ x 1))) must be evaluated (use calculus), where
> share is imported from the package calculus
It does. See above, my macro USE is called at run-time.
> I tried the following to show the issue:
>
> ? (unintern 'share)
> T
> ? (use calculus)
> NIL
Well here I get:
cl-user> (use calculus)
I'll use (calculus)
nil
> ? (values (find-symbol "SHARE") (symbol-package 'share))
> SHARE
> #<Package "/Users/mazeboard/workspace/ccl/CALCULUS.LISP">
A strange name for a package, but why not.
> ? (share '(fn x (+ x 1)))
> ... ; result of the function share imported from calculus
> ? (unuse calculus)
> NIL
Same here:
cl-user> (unuse calculus)
I unused (calculus)
nil
> ? (values (find-symbol "SHARE") (symbol-package 'share))
> SHARE
> #<Package "COMMON-LISP-USER"> ;;; after unuse calculus SHARE is not
> from calculus anymore
> ? (progn (use calculus) (values (find-symbol "SHARE") (symbol-package
> 'share)))
> SHARE
> NIL
> ?
>
> As you can see in the last expression (progn) even though we use
> calculus the symbol SHARE is
> not visible
In:
(in-package "COMMON-LISP-USER)
(with-package (calculus)
(share '(fn x (+ x 1))))
the symbols WITH-PACKAGE CALCULUS SHARE FN and X are all interned in the
package named "COMMON-LISP-USER" (unless you've used a package that
export them or you've imported them from another package).
WHEN are they interned? At READ-TIME!
Do the operator COMMON-LISP-USER:SHARE use the value of CL:*PACKAGE* at
RUN-TIME?
See my example, I used CL:*PACKAGE* at run-time twice:
- once explicitely by passing *package* to find-symbol.
- once implicitely by calling print which uses *package* to determine
how to print symbols.
Perhaps you could have a look at:
http://www.nhplace.com/kent/PS/Ambitious.html
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
More information about the Openmcl-devel
mailing list