From: Phil Stubblefield
Subject: Help with EVAL-WHEN
Date: 
Message-ID: <1992Jul28.033744.13313@CSD-NewsHost.Stanford.EDU>
I'm working on some software intended to run in several different
implementations.  In some of the implementations, a useful function FOO is
defined.  In the others, FOO is undefined, and so I've provided my own
definition.  What I'd like to be able to do is to execute my definition if
and only if the implementation doesn't already provide its own.

My code is isomorphic to the following:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (unless (fboundp 'foo)
    (eval-when (:compile-toplevel :load-toplevel :execute)

      (defconstant +used-to-compute-foo+ ...)

      (defgeneric foo (object))

      (defmethod foo ((object t))
        <code that uses the previously defined constant>)

      <more method definitions...>

      )))


At compile time under Franz Allegro CL 4.1 running on a SparcStation, I am
warned that the symbol +used-to-compute-foo+ is being declare special.  At
load time, I get the following error (reformatted):

Error: No methods applicable for generic function
       #<STANDARD-GENERIC-FUNCTION FIND-METHOD @ #x862e0e> with
       args (#<Function FOO @ #xb1f72e> NIL
       (#<BUILT-IN-CLASS SEQUENCE @ #x78b356>) NIL)
       of classes (FUNCTION NULL CONS NULL)
  [condition type: PROGRAM-ERROR]

Clearly, I have a incomplete and/or flawed model of EVAL-WHEN.  Can someone
enlighten me?

(For those who care, the actual instantiation of this problem uses the
function CLIM:PRESENTATION-TYPE-OF, which is defined in CLIM 1.1 but not in
CLIM 1.0.  Unfortunately, I know of no easy way to discriminate between the
two releases.)

-- 

Phil Stubblefield                                        (415) 325-7165
Rockwell Palo Alto Laboratory                    ····@rpal.rockwell.com

From: Sandra Loosemore
Subject: Re: Help with EVAL-WHEN
Date: 
Message-ID: <1992Jul28.120934.9306@cs.yale.edu>
The problem is that the code nested inside the UNLESS is not at 
top-level.  EVAL-WHEN can cause compile-time evaluation only when
it appears at top-level, so the inner EVAL-WHEN in your code doesn't
do anything useful.  Defining forms such as DEFCONSTANT also have
no compile-time effect unless they appear at top-level.

A better way to do this kind of conditionalization would be something
like this:

(eval-when (:compile-toplevel :load-toplevel)
  (if (fboundp 'foo) (pushnew :foo-feature *features*)))

#-:foo-feature
(progn
  ; code to define your own foo goes here.
  )

Notice that PROGN does pass "top-level-ness" on to its subforms.

-Sandra
From: Phil Stubblefield
Subject: Re: Help with EVAL-WHEN
Date: 
Message-ID: <1992Jul28.183237.25456@CSD-NewsHost.Stanford.EDU>
In article <·····················@cs.yale.edu> ················@CS.YALE.EDU
 (Sandra Loosemore) writes:
>The problem is that the code nested inside the UNLESS is not at 
>top-level.  EVAL-WHEN can cause compile-time evaluation only when
>it appears at top-level, so the inner EVAL-WHEN in your code doesn't
>do anything useful.  Defining forms such as DEFCONSTANT also have
>no compile-time effect unless they appear at top-level.

Sandra,

I think my confusion stems from a misunderstanding of X3J13 action #50, or
DEFINING-MACROS-NON-TOP-LEVEL:ALLOW, if you don't remember off the top of
your head.  :)  I had interpreted the various CLtL/2 references to this vote
to mean that these defining forms would work exactly the same in non-
top-level contexts.  Rereading the top paragraph on p. 84 helped to clarify
that the real issue behind this vote is that the various defining forms
must capture the current lexical environment correctly, although it is
still the case that "certain compile-time side effects of these defining
forms are performed only when the defining forms occur at top level."

>A better way to do this kind of conditionalization would be something
>like this:
>
>(eval-when (:compile-toplevel :load-toplevel)
>  (if (fboundp 'foo) (pushnew :foo-feature *features*)))
>
>#-:foo-feature
>(progn
>  ; code to define your own foo goes here.
>  )
>
>Notice that PROGN does pass "top-level-ness" on to its subforms.
>
>-Sandra

Thanks much!
-- 

Phil Stubblefield                                        (415) 325-7165
Rockwell Palo Alto Laboratory                    ····@rpal.rockwell.com