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


Reply via email to