On Wed, 2002-10-23 at 23:02, Pierre R. Mai wrote:
> 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?
Nothing. This is a great suggestion, thanks! I'm learning many of these
techniques for the first time and I overlooked the idea. That's all!
> 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)))
Thanks again. It put me on the track of an arguably more elegant
solution: why not use the symbol's property list!
(defun test (&rest args)
(declare (ignore args))
nil)
(defmacro defun-grab (name lambda-list &body body)
(let ((defun-form `(defun ,name ,lambda-list ,@body)))
`(progn
,defun-form
(setf (get ',name 'source) ',defun-form))))
(test
(defun-grab plus1 (number) (1+ number))
(write (plus1 1))
(write (get 'plus1 'source)))
;;just to make sure it also works at the top level
(write (plus1 1))
(write (get 'plus1 'source))
This also works perfectly, there is no need for a separate global
variable to hold the function sources and the variable's value is left
unbound.
This leaves us with the peculiar situation that it appears easier to
create a global function within a function using a macro and attach a
global property to that function than it is to directly create a global
variable using a macro within a function.
Regards,
Adam