[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