[gambit-list] Newbie: define-macro question

Will Farr wmfarr at gmail.com
Thu Aug 18 15:33:33 EDT 2005


On 8/18/05, Logan, Patrick D <patrick.d.logan at intel.com> wrote:
> > In your opinion, is it appropriate to use a macro to abstract away
> > repetitive boiler-plate code? Or is this better done in a procedure?

Two more places where a simple procedure won't do, but you have
boilerplate code which calls for a macro are (both have occurred in my
recent coding work on n-body integrators):

1. Various repetitive binding constructs i.e.:

(let ((m (body-m b))
      (q (body-q b))
      (p (body-p b))
      (t (body-t b)))
  'do-something)

becomes 

(with-body (b) 'do-something)

This type of macro cannot be written with the syntax-rules defined in
R5RS (there's no way to introduce the literal identifier 'm into the
expansion of the macro), but can be written with the syntax-case
extension (which is available in gambit), though it's easiest with
define-macro:

(define-macro (with-body body . exprs)
  (let ((body-sim (car body)))
    `(let ((m (body-m ,body-sym))
           (q (body-q ,body-sym))
           (p (body-p ,body-sym))
           (t (body-t ,body-sym)))
       , at exprs)))

A fun exercise: convert this macro to (with-bodies (b1 b2 ...) ...)
which does the above if called like (with-bodies (b) ...), but does

(let ((m1 (body-m b-one))
      (m2 (body-m b-two))
      (m3 (body-m b-three))
      ...)
  'do-something)

if called like (with-bodies (b-one b-two b-three ...) 'do-something).

2. Making little sub-languages for specialized processing e.g.

(with-vectors (v1 v2 v3) (v1 <- (+ v2 v3)))

for summing up the vectors v2 and v3 and storing it in v1.  (I'm not
going to put this macro up because it's long---the code is buried in
this post: http://wmfarr.blogspot.com/2005/06/bigloo-macros-and-repl.html
.)

#1 involves introducing new bindings into a section of code, and #2
involves changing the evaluation rules for a piece of code (the vector
assignment is evaluated once for each index with the corresponding
variables bound to elements of a vector).  Procedures would not work
for either of them; you have to have a macro.

My point is to illustrate just how nice it is to have macros in a
language---and to encourage you to use macros to remove your
boiler-plate code!  These two macros have saved me literally thousands
of lines of typing (and made my code clearer) over the past month, and
they didn't even take very long to write.

Enjoy,
Will



More information about the Gambit-list mailing list