[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Libraries and repositories

Shriram Krishnamurthi writes
> Paul Graham wrote:
> > If it's only a couple lines, could you send us a def of
> > defmacro in terms of syntax-case?
> Eli Barzilay posted this to the PLT Scheme discussion list a few weeks 
> ago:
>   (define-syntax (define-macro stx)
>     (syntax-case stx ()
>      ((_ (macro . args) . body)
>       (syntax (define-macro macro (lambda args . body))))
>      ((_ macro transformer)
>       (syntax
>        (define-syntax (macro stx2)
>          (let ((v (syntax-object->datum stx2)))
>            (datum->syntax-object
>             stx2
>             (apply transformer (cdr v)))))))))
> In short, it's a macro-defining macro.  The point is, why settle for
> DEFINE-MACRO?  With this, you can create your own macro-defining macro
> notation.  You can't add hygiene after the fact, so this gives you the 
> choice of using it if you want it.

It may be more appealing to identify exactly the extra
machinery that a quondam defmacro user need learn in
order to proceed.  The extras are merely the coercion
procedures syntax-object->datum and
datum->syntax-object, with defmacro replaced by

1. A naive defmacro version of two-argument 'or' looks like

(define-macro or
  (lambda args
    `(let ((__tmp ,(car args)))
        (if __tmp __tmp ,(cadr args)))))

Well, that isn't quite defmacro (for which, see
ps).  It is actually a somewhat Schemely define-macro,
with the transformer being explicitly identified as a
procedure.  (This is really a poor macro -- for one
thing it accepts more arguments than two but doesn't
act on them.  But never mind -- that's not the point of
this exercise.)

2. How does one translate this to define-syntax & friends?

(define-syntax or
  (lambda (so)
    (datum->syntax-object so
      (let ((so-d (syntax-object->datum so)))
        `(let ((__tmp ,(cadr so-d)))
           (if __tmp __tmp ,(caddr so-d)))))))

3. How do we abstract away the calls to the coercion
procedures, in effect regaining define-macro?

(define-syntax define-macro
  (lambda (so)
    (datum->syntax-object so
      (let ((so-d (syntax-object->datum so)))
        `(define-syntax ,(cadr so-d)
           (let ((xmfr ,(caddr so-d)))
             (lambda (so)
               (datum->syntax-object so
                 (apply xmfr 
                   (cdr (syntax-object->datum so)))))))))))

4. How do we define a naive two-argumet 'or' in terms of
_this_ define-macro?  Hark back to 1. 

syntax-case doesn't enter the picture at all.  


ps: A more CL-like defmacro would be

(define-syntax defmacro
  (lambda (so)
    (datum->syntax-object so
      (let ((so-d (syntax-object->datum so)))
        `(define-syntax ,(cadr so-d)
           (let ((xmfr (lambda ,@(cddr so-od))))
             (lambda (so)
               (datum->syntax-object so
                 (apply xmfr
                   (cdr (syntax-object->datum so)))))))))))