[Openmcl-devel] with-package

Taoufik Dachraoui dachraoui.taoufik at gmail.com
Sat Jan 12 06:48:44 PST 2013


Not exactly what I meant

(use file) ;will create a package <current-dir>/file.lisp with a nickname
file
and load the file, then it imports all the external symbol from file (it
first saves the
symbols with the same name, if they exist, in the current package *package*)

(unuse file) ;; unintern all external symbol of file and restores the saved
symbols (if they exist)


now, I use this as follows (from top level)

? *package*
#<Package "COMMON-LISP-USER">
? (defun share (x) (+ x 1))
SHARE
? (use calculus) ;;;; calculus exports the symbol SHARE
NIL
? (find-package :calculus)
#<Package "/Users/mazeboard/workspace/ccl/CALCULUS.LISP">
? (share 3)  ;; uses the symbol CALCULUS::SHARE
.3 boxes:(NIL)
.r:3
3
? (unuse calculus)  ; this will delete package calculus and restore the
symbol COMMON-LISP-USER::SHARE
NIL
? (share 3)  ;; using the restored symbol COMMON-LISP-USER::SHARE
4
?

Now, I wanted to define with-package

(defmacro with-package ((&rest names) &body body)
  `(progn
     (use , at names)
     , at body
     (unuse ,@(reverse names))))


But the problem when I use with-package as follows:

? *package*
#<Package "COMMON-LISP-USER">
?  (with-package (calculus) (share 3))
NIL  ;;; I did not use CALCULUS::SHARE
? (share 3)
4
?

I want to find a solution to be able to use with-package such that the
imported symbols from calculus are interned in the current package  before
reading and/or compiling the body of with-package

I want (with-package (names) body) to behave exactly as (toplevel)
? (use names)
? body
? (unuse (reverse names))


Taoufik


On Sat, Jan 12, 2013 at 3:12 PM, Pascal J. Bourguignon <
pjb at informatimago.com> wrote:

> 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 {}.
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20130112/a7b938f4/attachment.htm>


More information about the Openmcl-devel mailing list