Subject: Re: How to define my own special forms in SCHEME ?
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1999/02/20
Newsgroups: comp.lang.scheme
Message-ID: <7amaid$78090@fido.engr.sgi.com>
Jim Hefferon <jheffero@nyx10.nyx.net> wrote:
+---------------
| ...IMH(and not-well-informed)O there's kind of a lot of problems with
| Scheme and macros.  Isn't it right that in R4RS there are a number
| of different approaches to macros, and the idea of the writers is
| that the `right' one will emerge in the marketplace of ideas?  Of
| course, I'm all for the marketplace of ideas but I don't get any
| of the different ways given there, and I am left with the feeling 
| that programs that I write following one pattern are likely to
| have to be rewritten.
+---------------

My personal [and politically incorrect, I admit] approach to this
is to -- exactly once for each new Scheme I run into -- figure our
what low-level macro facility it has (almost all of them have *something*)
and how to write a CL-style "defmacro" macro in whatever low-level macro
facility there is. Then from then on I do everything using "defmacro"...

For example, in Elk or Gambit, you could say:

	(define-macro (defmacro name args . body)
	  `(define-macro (,name . ,args) ,@body))

and in MzScheme (which doesn't permits the sugared "define"), you
could say (if you didn't want to load the "compat" library, which
already has a definition for "defmacro" in it):

	(define-macro defmacro
	  (lambda (name args . body)
	    `(define-macro ,name (lambda ,args ,@body))))

and SCM already has "defmacro" built in, and so on...

[And yes, you can make it work in SIOD, too, though it's more hairy.
See the definition of "defmac" in the file "siod.scm" in the distribution,
and clone a suitable mutation.]

Then you can do stuff like this [borrowing the "map*" macro from
Andy Gaynor's recent post], and it will work in *any* of them:

	> (defmacro map* (parameters lists . body)
	    `(map (lambda ,parameters . ,body) . ,lists))

	> (map* (a b) ('(1 2 3) '(4 5 6)) (list a b))
	==> ((1 4) (2 5) (3 6))

	> (map* (a b) ('(1 2 3) '(4 5 6)) (+ a b))
	==> (5 7 9)
	> 

-Rob

p.s. Unfortunately, my strategy for using "CL-like defmacro" for
portability doesn't extend to CL itself! The Common Lisp equivalent
for Scheme's "map" is "mapcar", so the definition of "map*" is
slightly different... (*sigh*)

-----
Rob Warnock, 8L-855		rpw3@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
2011 N. Shoreline Blvd.		FAX: 650-964-0811
Mountain View, CA  94043	PP-ASEL-IA