Subject: Re: Extent of definitions in environments (Was: First draft ...)
From: rpw3@rpw3.org (Rob Warnock)
Date: Mon, 19 Jul 2004 23:54:48 -0500
Newsgroups: comp.lang.lisp
Message-ID: <q4adndnLXMYFOGHdRVn-jw@speakeasy.net>
Alan Crowe  <alan@cawtech.freeserve.co.uk> wrote:
+---------------
| ...things will not go well. The compiler will put object code
| for DUPLICATE into the output file, but not add it to the
| evaluation environment
| 
| ;;; Compiling file single-file-fancy.lisp
| ; While compiling (:TOP-LEVEL-FORM "single-file-fancy.lisp" 106):
| Error: attempt to call `DUPLICATE' which is an undefined function.
| 
| The minimal fix is to use eval-when
| 
| (eval-when (:compile-toplevel)
|   (defun duplicate (form)
|     (list form form)))
| 
| (defmacro do-twice(form)
|   (cons 'progn (duplicate form)))
| 
| (do-twice (print "Oh dear "))
| 
| Compiling works because the definition of DUPLICATE went
| into the compilers evaluation environment and was available
| for expanding the macro.
+---------------

Yes, but interactive development is now broken!! [1]

    > (eval-when (:compile-toplevel)
        (defun duplicate (form)
	  (list form form)))

    NIL
    > (defmacro do-twice(form)
        (cons 'progn (duplicate form)))

    DO-TWICE
    > (do-twice (print "Oh dear "))
    ; 

    ; Warning: This function is undefined:
    ;   DUPLICATE

    Error in KERNEL:%COERCE-TO-FUNCTION:  the function DUPLICATE is undefined.
       [Condition of type UNDEFINED-FUNCTION]

    Restarts:
      0: [ABORT] Return to Top-Level.

I think you have no choice but to use:

    > (eval-when (:compile-toplevel :load-topleve :execute)
        (defun duplicate (form)
	  (list form form)))


-Rob

[1] At least, in implementations that don't automatically compile
    everything.

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607