[plt-dev] syntax-case behaving differently

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu May 7 17:09:24 EDT 2009

At Thu, 07 May 2009 22:33:06 +0200, "Marijn Schouten (hkBst)" wrote:
> I found a difference in running a file with "mzscheme -f <file>" and with
> "plt-r6rs <file>" involving syntax-case. For the first you should comment the
> import. Then the first will error:
> cdr: expects argument of type <pair>; given #<syntax:blah>
> and the second will produce the expected output:
> (a b (+ c -1) d e)
> The code is:
> (import (rnrs)) ;comment this line for mzscheme
> (define make-next-coords
>   (lambda (x)
>     (with-syntax (((name ... pos inc) x))
>       (let ((pos (syntax->datum #'pos)))
>         (let f ((names #'(name ...))(pos pos))
>           (with-syntax (((name rest ...) names))
>             (if (zero? pos)
>                 #'((+ name inc) rest ...)
>                 #`(name #,@(f (cdr names)(- pos 1))))))))))
> (write (syntax->datum (make-next-coords #'(a b c d e 2 -1))))
> Is this a bug or is there another explanation?

R6RS and PLT Scheme have different rules about syntax-object wrapping.

 #'(name ...)

generates a list in R6RS, but it's a wrapped[*] syntax object in PLT
Scheme. In the latter case, `syntax->list' is the simplest way to
convert the syntax object to a list.

One reason for this difference is that the implicit
procedure-application form is lexically scoped in PLT Scheme (and you
can redefine it by binding `#%app'), which means that a lexical context
must be attached to parentheses (roughly speaking).

[*] "Wrapped syntax object" is R6RS terminology. In PLT Scheme
    terminology, all "syntax object" always implies a wrapper.

Posted on the dev mailing list.