[plt-scheme] syntax/cx+loc
Matthew Flatt writes:
> At Tue, 22 Mar 2005 11:19:37 -0500, Doug Orleans wrote:
> > (module m2 mzscheme
> > (provide helper2)
> > (define (helper2 stx)
> > (syntax-case stx ()
> > ((a . b)
> > (syntax (list . b))))))
> >
> > (module m3 mzscheme
> > (require-for-syntax m2)
> > (provide macro2)
> > (define-syntax (macro2 stx)
> > (helper2 stx)))
> >
> > (require m3)
> > (macro2 1 2 3) ; => stdin::324: compile: bad syntax; function application is
> > not allowed, because no #%app syntax transformer is bound in: (list 1 2 3)
>
> Probably the best solution to this problem is to add
>
> (require-for-template mzscheme)
>
> to `m2'.
Thanks, I hadn't noticed that before.
> > So instead of using `syntax' (or `syntax/loc', which copies the source
> > location information), now I use `syntax/cx+loc', which copies both
> > the lexical context and source location information:
> >
> > (define-syntax syntax/cx+loc
> > (syntax-rules ()
> > ((_ source-stx-expr template-expr)
> > (let ((source-stx source-stx-expr))
> > (datum->syntax-object
> > source-stx (syntax-e #'template-expr) source-stx)))))
> >
> > This seems to work fine, so I thought I'd share it.
>
> I think this is probably not want you want. First, it makes your macro
> slightly non-hygienic. Second, if you use `syntax/cx+loc' instead of
> `syntax' in `m2' above, you end up with an `#%app' binding in your
> example, but not a `list' binding.
That was a bad example, sorry... What I'm actually doing is taking
application expressions apart and putting parts of them back together--
I'm not introducing any new symbols. Then `syntax/cx+loc' seems to work:
> (module h mzscheme
(define-syntax syntax/cx+loc
(syntax-rules ()
((_ source-stx-expr template-expr)
(let ((source-stx source-stx-expr))
(datum->syntax-object
source-stx (syntax-e #'template-expr) source-stx)))))
(define (helper stx)
(syntax-case stx ()
((a b c . d)
(syntax/cx+loc stx (b . d)))))
(provide helper))
> (require-for-syntax h)
> (define-syntax (macro stx) (helper stx))
> (macro + 1 2 3)
5
Is this still non-hygienic? It seems like requiring mzscheme for
templates is non-hygienic, since this would ignore any local
definition for #%app. Is that right? Is there a hygienic way to do
this?
--dougo at place.org