[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
define-syntax.
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.
--d
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)))))))))))