[plt-scheme] literal matching in syntax-case

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Apr 30 04:36:30 EDT 2007

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



Posted on the users mailing list.