From: Paul von Hippel
Subject: Question:  macros and defstruct
Date: 
Message-ID: <1993Sep8.053419.29559@leland.Stanford.EDU>
The following question asks how to use macros to get around the cumbersome  
access functions built into defstruct.  Please send answers to  
···@ccrma.stanford.edu.

My program uses the following user defined data-structure.

(defstruct stimulus-class 
  (fraction-late 0)
  (dB-quieter 0)
  (answers nil)
  (threshold-range '(0 0))
  (above-threshold nil)
  (enough-answers nil)
  )

Whose components can only be accessed by such forms as 

(stimulus-class-fraction-late class)

where class is a variable of the defined type.  I have defined macros that  
make this a little more concise, viz.

(defmacro above-threshold ()
  `(stimulus-class-above-threshold *class*)
  )

(defmacro below-threshold ()
  `(stimulus-class-below-threshold *class*)
  )

(defmacro dB-quieter ()
  `(stimulus-class-dB-quieter *class*)
  )

(defmacro fraction-late ()
  `(stimulus-class-fraction-late *class*)
  )

(defmacro enough-answers ()
  `(stimulus-class-enough-answers *class*)
  )

(defmacro threshold-range ()
  `(stimulus-class-threshold-range *class*)
  )

where *class* is a global variable.

Obviously, there is a lot of duplicated code here.  Not only do all the  
macros have a parallel definitions, each one uses its name (e.g.,  
threshold-range) in its definition (e.g., stimulus-class-threshold-range).   
I wonder if there is a way to define all these macros - or similar ones -  
in one fell swoop.
From: Kelly Murray
Subject: Re: Question:  macros and defstruct
Date: 
Message-ID: <26qdtiINNr5b@no-names.nerdc.ufl.edu>
In article <·····················@leland.Stanford.EDU>, ···@cmn10.Stanford.EDU (Paul von Hippel) writes:
|> The following question asks how to use macros to get around the cumbersome  
|> access functions built into defstruct.  Please send answers to  
|> ···@ccrma.stanford.edu.
|> 

What you want is your own "defstruct" macro that defines the additional macros.
So you can define the defstruct like this:

(defstruct-with-macros-accessing-the-global *class* stimulus-class 
  (fraction-late 0)
  (answers nil)
  )

which will expand into a defstruct and the additional macros.
Howerver, let me say that these additional macros might be considered
"macro abuse", since you are defining operators that hide important
aspects of how your program works.  Here's a version with bugs:

(defmacro defstruct-with-macros-accessing-the-global (global struct &rest slots)
  `(progn
     (defstruct ,struct ,@slots)  ;; Define the normal defstruct
     ;; Define the additional macros
     ,@(mapcar #'(lambda (slot-spec)
                   (let* ((slot-name (car slot-spec))
                          (macro-name (concat-symbols struct slot-name)))
	             `(defmacro ,slot-name () (,macro-name ,global))))
               slots)
     )
  )