From: Andrew Cooke
Subject: eval-when?
Date: 
Message-ID: <7vnko2$icn$1@nnrp1.deja.com>
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.

From: Barry Margolin
Subject: Re: eval-when?
Date: 
Message-ID: <C4JT3.22$Q6.936@burlma1-snr2>
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.
From: Christopher R. Barry
Subject: Re: eval-when?
Date: 
Message-ID: <87yacgow1e.fsf@2xtreme.net>
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
From: Andrew Cooke
Subject: Re: eval-when?
Date: 
Message-ID: <7vou34$g0g$1@nnrp1.deja.com>
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.
From: Erik Naggum
Subject: Re: eval-when?
Date: 
Message-ID: <3150616834270740@naggum.no>
* 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
From: Pierre R. Mai
Subject: Re: eval-when?
Date: 
Message-ID: <87so2ndbor.fsf@orion.dent.isdn.cs.tu-berlin.de>
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]