Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

eval-when?

1 view
Skip to first unread message

Andrew Cooke

unread,
Nov 2, 1999, 3:00:00 AM11/2/99
to

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.

Barry Margolin

unread,
Nov 2, 1999, 3:00:00 AM11/2/99
to
In article <7vnko2$icn$1...@nnrp1.deja.com>,

Andrew Cooke <and...@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, bar...@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.

Christopher R. Barry

unread,
Nov 3, 1999, 3:00:00 AM11/3/99
to
Barry Margolin <bar...@bbnplanet.com> writes:


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

Andrew Cooke

unread,
Nov 3, 1999, 3:00:00 AM11/3/99
to

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

Erik Naggum

unread,
Nov 3, 1999, 3:00:00 AM11/3/99
to
* 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

Pierre R. Mai

unread,
Nov 3, 1999, 3:00:00 AM11/3/99
to
Andrew Cooke <and...@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 <pm...@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]

0 new messages