[plt-scheme] literal matching in syntax-case
At Mon, 30 Apr 2007 03:48:21 -0400 (EDT), Dimitris Vyzovitis wrote:
> I am seeing unexpected behavior from literal matching in syntax case and
> custom language modules. An example follows where redefinition of define
> in a custom language breaks a macro in plain mzscheme that literal
> matches on define.
>
> My understanding of literal matching is that they should match regardless
> of such redefinitions, but perhaps I am missing something here.
Literal matching is based on `module-identifier=?', which means that it
compares based on binding.
Here's an example where `foo' corresponds to `define', so it matches:
> (define (is-define? id)
(syntax-case id (define)
[define #t]
[_ #f]))
> (is-define? #'define)
#t
> (is-define? #'foo)
#f
> (require (rename mzscheme foo define))
> (is-define? #'foo)
#t
> (foo x 5)
> x
5
Going back to your examples:
> macro.ss:
> (module macro mzscheme
> (define-syntax (test stx)
> (syntax-case stx (define)
> ((_ (define id expr)) (syntax #t))
> (_ (raise-syntax-error #f "no milk today" stx))))
> (provide (all-defined)))
This `syntax-case' matches bindings using MzScheme's `define'.
> lang.ss:
> (module lang mzscheme
> (define-syntax (my-define stx)
> (syntax-case stx ()
> ((_ id expr)
> #'(define id expr))))
>
> (provide (all-from-except mzscheme define)
> (rename my-define define)))
This module exports a different binding as `define'.
> repl:
> Welcome to MzScheme v369.11 [3m], Copyright (c) 2004-2007 PLT Scheme Inc.
> > (require "macro.ss")
> > (test (define x y))
> #t
> > (require "lang.ss")
> > (test (define x y))
> stdin::81: test: no milk today in: (test (define x y))
In the last expression, `define' is no longer bound as MzScheme's
`define'.
In case it's relevant: you can use `syntax-case*' to supply a specific
matching predicate to take the place of `module-identifier=?'.
Matthew