[plt-scheme] syntax/cx+loc

From: Doug Orleans (dougo at place.org)
Date: Sat Mar 26 21:26:34 EST 2005

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



Posted on the users mailing list.