Adam Warner <[EMAIL PROTECTED]> writes:
> On Wed, 2002-10-23 at 07:29, William Harold Newman wrote:
>>
>> On Tue, Oct 22, 2002 at 02:34:19PM +0200, Gerd Moellmann wrote:
>> >
>> > Adam Warner <[EMAIL PROTECTED]> writes:
>> >
>> > > In: defun-grab plus1
>> > > (defun-grab plus1 (number) (1+ number))
>> > > --> progn eval-when defparameter progn
>> > > ==>
>> > > (setq plus1 '(defun plus1 (number) (1+ number)))
>> > > Warning: Undefined variable: plus1
>> >
>> > I think this from CLHS might be relevant:
>> >
>> > defparameter and defvar normally appear as a top level form, but it is
>> > meaningful for them to appear as non-top-level forms. However, the
>> > compile-time side effects described below only take place when they
>> > appear as top level forms.
>> >
>> > [...]
>> >
>> > Side Effects:
>> >
>> > If a defvar or defparameter form appears as a top level form, the
>> > compiler must recognize that the name has been proclaimed
>> > special. However, it must neither evaluate the initial-value form nor
>> > assign the dynamic variable named name at compile time.
>> >
>> > There may be additional (implementation-defined) compile-time or
>> > run-time side effects, as long as such effects do not interfere with
>> > the correct operation of conforming programs.
>>
>> I was motivated to rip so much stuff apart in pursuit of correct
>> EVAL-WHEN behavior ca. sbcl-0.7.0 not because I do a lot of exotic
>> things with EVAL-WHEN in application code, but because so many of the
>> magic-at-toplevel operators like DEFUN, DEFSTRUCT, and DEFVAR are
>> naturally defined in terms of EVAL-WHEN. Then when EVAL-WHEN behaves
>> correctly, all sorts of special cases, e.g. Adam's and also
>> (defun foo (x)
>> (if x
>> (defstruct foo a)
>> (defstruct foo b c)))
>> (compile *)
>> start to work as ANSI specifies.
>
> I hope you can achieve this aim William and the results cross-pollinate
> into CMUCL.
I think there is a certain amount of talking past each other involved
here. AFAICT, your code really relies on behaviour that isn't
mandated by ANSI at all, namely that the compiler performs special
proclamations even for non-top-level defparameters. This should IMHO
never happen, because it destroys the users ability to selectively
perform defparameters at run-time, e.g.
(defun foo (x)
(if x
(defparameter a x)
(defparameter b x)))
The compiler must not cause both a and b to be proclaimed special, all
of a sudden, just by compiling this function.
[...]
> I think this fully addresses Raymond's question "perhaps you could
> explain why you think you need to do this and what you really want to
> do."
The thing I don't really understand is
a) why all the defun forms have to be grabbed at compile-time,
probably in order to process them at load-time.
I.e. wouldn't it make sense to move the processing of them to
compile-time, too, so that the processing could emit code that did
the really processing at runtime?
(For that matter I don't understand the reason for the eval-when
form around the defun-form, either)
b) why, even if this is the case, they have to be stored in thousands
of newly introduced special variables (at compile-time and
load-time even)
I.e. what do the special variables buy you that e.g. storing the
associations on one global special variable wouldn't?
For example:
(defun test (&rest args)
(declare (ignore args))
nil)
(defparameter *grabbed-defuns* (make-hash-table :test 'equal))
(defmacro defun-grab (name lambda-list &body body)
(let ((defun-form `(defun ,name ,lambda-list ,@body)))
`(progn
(setf (gethash ',name *grabbed-defuns*) ',defun-form)
,defun-form)))
(defun access-me (name)
(or (gethash name *grabbed-defuns*)
(error "Unknown defun named ~A~%" name)))
(test
(defun-grab plus1 (number) (1+ number))
(write (access-me 'plus1)))
c) If it really turns out that you need to be doing what you are
doing, you can likely make this work in a hackish sort of way by
including a special proclamation in your macro expander, e.g.:
(defmacro defun-grab (name lambda-list &body body)
(let ((defun-form `(defun ,name ,lambda-list ,@body)))
(proclaim `(special ,name))
`(progn
(eval-when (:compile-toplevel :load-toplevel :execute)
(defparameter ,name ',defun-form))
(eval-when (:compile-toplevel :load-toplevel :execute)
,defun-form))))
Though again, I really wouldn't want to be doing this, at all.
Regs, Pierre.
--
Pierre R. Mai <[EMAIL PROTECTED]> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein