[plt-scheme] macro type

From: Eli Barzilay (eli at barzilay.org)
Date: Thu Jul 13 05:42:23 EDT 2006

On Jul 13, Ivanyi Peter wrote:
> [...]
> and in this case I also would like to have
> 
> > (macro? cond)
> #t
> 
> Is it possible to achieve the above?

No.  At least not with any modern Scheme.  The thing is that macros
are syntactic things that get expanded away when it gets to the
runtime, and the above use of `cond' does not expand to anything.
Think about the phase separation -- the two worlds (macro-expansion
time and run-time) are completely separate in the sense that they
don't exist at the same time -- so in the above expression either cond
has a syntax-transformer value and `macro?' is just a piece of data
(syntax), or `macro?' is a function and `cond' should have expanded
away.

If you *really* want to make the above interaction true, you could do
one of two things:

1. Use the fact that MzScheme can have "identifier-macros" that are
   used even when used as an expression -- and make `(cond ...)'
   expand as usual, but `cond' expand to some `(make-macro-object 'cond)'.
   This would require a change in MzScheme to have all macros do this,
   but it's impracticaly anyway since it won't work with real uses of
   identifier macros.  (Search for `syntax-id-rules' for examples.)

2. Define `macro?' as a macro, that looks at the given syntax and if
   it has a syntax-time transformer value, expand (not evaluate) to
   #t, otherwise expand to #f.  The problem with this is that it's
   expansion, not evaluation -- so as far as the compiler goes,
   writing `(macro? cond)' is the same as writing `#t'.  Specifically,
   this:
     (define (foo x) (macro? x))
   will always be false (since `x' is not a macro), and in any case,
   `foo' is itself a function, so it again cannot be used as:
      (foo macro)
   for the same reason as above.

But *even if* you had some way of achieving that and get a value for
`cond', what will you do with this value?  The only use for it would
be to use it as a syntax -- expand it or evaluate a piece of an
expression, and both of these are available anyway.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!


Posted on the users mailing list.