Hi,
I have some code that may (or may not) use another package. If the code
is being used independently, I need to define something myself. So I
have some top-level code that looks like:
(cond ((find-package "ZB")
(print "using zebu"))
(t
(print "no zebu")
(defstruct kb-domain)))
But this doesn't work when the other package is present - kb-domain ends
up being defined in the current package and in ZB. I guess (I'm new to
this) that kb-domain as a symbol has been created by the reader, hence
the conflict.
So I thought maybe this is what eval-when was for, and changed the code
to
(cond .....
(t
(eval-when (:execute) (defstruct kb-domain))))
But this also fails, in the same way (I'm not terribly surprised, if my
explanation above is correct). Can anyone tell me what I am doing wrong
(at any level of abstraction below "using Lisp") - or, better, what I
should be doing here?
Cheers (and I have Graham's On Lisp on order....!)
Andrew
http://www.andrewcooke.free-online.co.uk/index.html
Sent via Deja.com http://www.deja.com/
Before you buy.
In article <············@nnrp1.deja.com>,
Andrew Cooke <······@andrewcooke.free-online.co.uk> wrote:
>
>
>Hi,
>
>I have some code that may (or may not) use another package. If the code
>is being used independently, I need to define something myself. So I
>have some top-level code that looks like:
>
>(cond ((find-package "ZB")
> (print "using zebu"))
> (t
> (print "no zebu")
> (defstruct kb-domain)))
>
>But this doesn't work when the other package is present - kb-domain ends
>up being defined in the current package and in ZB. I guess (I'm new to
>this) that kb-domain as a symbol has been created by the reader, hence
>the conflict.
>
>So I thought maybe this is what eval-when was for, and changed the code
>to
>
>(cond .....
> (t
> (eval-when (:execute) (defstruct kb-domain))))
>
>But this also fails, in the same way (I'm not terribly surprised, if my
>explanation above is correct). Can anyone tell me what I am doing wrong
>(at any level of abstraction below "using Lisp") - or, better, what I
>should be doing here?
As you guessed, the symbol is being created by the reader. The reader
operates before the expression is compiled or executed, so the eval-when
takes place too late to solve this.
The only way to solve this is to defer creating the symbol until much
later, which requires using EVAL:
(if (find-packet "ZB")
(print "using zebu")
(progn
(print "no zebu")
(eval `(defstruct ,(intern "KB-DOMAIN")))))
--
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <······@bbnplanet.com> writes:
> In article <············@nnrp1.deja.com>,
> Andrew Cooke <······@andrewcooke.free-online.co.uk> wrote:
> >
> >
> >Hi,
> >
> >I have some code that may (or may not) use another package. If the code
> >is being used independently, I need to define something myself. So I
> >have some top-level code that looks like:
> >
> >(cond ((find-package "ZB")
> > (print "using zebu"))
> > (t
> > (print "no zebu")
> > (defstruct kb-domain)))
> >
> >But this doesn't work when the other package is present - kb-domain ends
> >up being defined in the current package and in ZB. I guess (I'm new to
> >this) that kb-domain as a symbol has been created by the reader, hence
> >the conflict.
> >
> >So I thought maybe this is what eval-when was for, and changed the code
> >to
> >
> >(cond .....
> > (t
> > (eval-when (:execute) (defstruct kb-domain))))
> >
> >But this also fails, in the same way (I'm not terribly surprised, if my
> >explanation above is correct). Can anyone tell me what I am doing wrong
> >(at any level of abstraction below "using Lisp") - or, better, what I
> >should be doing here?
>
> As you guessed, the symbol is being created by the reader. The reader
> operates before the expression is compiled or executed, so the eval-when
> takes place too late to solve this.
>
> The only way to solve this is to defer creating the symbol until much
> later, which requires using EVAL:
>
> (if (find-packet "ZB")
> (print "using zebu")
> (progn
> (print "no zebu")
> (eval `(defstruct ,(intern "KB-DOMAIN")))))
But READ will grab one top-level form at a time. What's wrong with
creating the symbol and immediately getting rid of it if he wants to
avoid having KB-DOMAIN remaining interned when package ZB exists? Why
not just do:
(unless (find-package "ZB")
(print "no zebu")
(defstruct kb-domain))
;; KB-DOMAIN interned at this point no matter what. READ will now
;; gobble the next form.
(when (find-package "ZB")
(print "using zebu")
(unintern 'kb-domain))
;; KB-DOMAIN non-existant at this point if ZB exists.
If this won't work for Andrew, I can probably concoct something more
clever....
Christopher
Thanks for the replies. I thought of hiding the name last night (when I
should have been sleeping...), but didn't know about intern.
Cheers,
Andrew
Sent via Deja.com http://www.deja.com/
Before you buy.
* Andrew Cooke
| I have some code that may (or may not) use another package. If the code
| is being used independently, I need to define something myself. So I
| have some top-level code that looks like:
|
| (cond ((find-package "ZB")
| (print "using zebu"))
| (t
| (print "no zebu")
| (defstruct kb-domain)))
|
| But this doesn't work when the other package is present - kb-domain ends
| up being defined in the current package and in ZB. I guess (I'm new to
| this) that kb-domain as a symbol has been created by the reader, hence
| the conflict.
you guessed right.
| Can anyone tell me what I am doing wrong (at any level of abstraction
| below "using Lisp") - or, better, what I should be doing here?
you can easily use the reader to support this shared-mode development.
the key is to use #+ and #- and to add your own feature to the *FEATURES*
list. to make sure this happens at the right time, you need to keep a
few things straight, however.
;;first set up the feature in the reader -- make sure the value is harmless
#.(progn
(if (find-package "ZB")
(pushnew :zebu *features*)
(drop :zebu *features*))
nil)
;;now we can use conditional reader forms to select or skip forms
#+zebu (print "using zebu")
#-zebu (print "no zebu")
hope this helps.
#:Erik
Andrew Cooke <······@andrewcooke.free-online.co.uk> writes:
> I have some code that may (or may not) use another package. If the code
> is being used independently, I need to define something myself. So I
> have some top-level code that looks like:
>
> (cond ((find-package "ZB")
> (print "using zebu"))
> (t
> (print "no zebu")
> (defstruct kb-domain)))
>
> But this doesn't work when the other package is present - kb-domain ends
> up being defined in the current package and in ZB. I guess (I'm new to
> this) that kb-domain as a symbol has been created by the reader, hence
> the conflict.
Others have pointed out the problem with your approach. I'd like to
suggest another approach:
a) Either Zebu already defines a feature you can use, or you can
define it yourself, when you find the Zebu package with
(eval-when (:compile-toplevel)
(when (find-package "ZB")
(pushnew :zebu *features*)))
Depending on your organization of source files (and your
implementation), the compile-time environment might or might not
remain present at the time other files are compiled, so you might
want to include :load-toplevel in the eval-when to propagate your
change to the load-time environment (which should influence future
compile-time environments). Or you put the above at the start of
all your relevant files.
b) Then you can use the conditional reader syntax (#+ / #-) to decide
whether to define things or not (you just have to make sure that
the form that modifies *features* isn't included in the same top-
level form, or your modification will be too late to have any
effect):
#-ZEBU
(defstruct kb-struct
...)
Regs, Pierre.
--
Pierre Mai <····@acm.org> PGP and GPG keys at your nearest Keyserver
"One smaller motivation which, in part, stems from altruism is Microsoft-
bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]