[racket] syntax-case literals matching in a procedure defined via begin-for-syntax vs (require (for-syntax ...))

From: YC (yinso.chen at gmail.com)
Date: Mon Aug 9 04:23:00 EDT 2010

Hi all -

I am running into a difference of behaviors when I define a procedure with
syntax-case via `begin-for-syntax` versus requiring it from another module
via (require (for-syntax ...)).  It seems that if the procedure has
syntax-case literals defined, the literal-matching works if the procedure is
defined via `begin-for-syntax`, but not when imported via
`require`/`for-syntax`.

Any idea on what I am missing/misusing here?

Below is an example with literal.ss and test-literal.ss showing that it does
not work:

;; literal.ss - cond* matches a cond-like syntax and convert it to an nested
if syntax. has an `else` syntax-case literal
#lang scheme/base
(define (cond* stx)
  (syntax-case stx (*else*)
    ((~)
     #`(void))
    ((~ (*else* exp exp2 ...))
     #`(begin (void) exp exp2 ...))
    ((~ (test exp exp2 ...) rest ...)
     #`(if test
           (begin exp exp2 ...)
           #,(cond* #`(cond* #,@#'(rest ...)))))
    ))

(provide cond*)


And test-literal.ss requires literal.ss via for-syntax, where `cond/` uses
`cond*`, and it resulted in an error, because the else arm is transformed
via the `if` arm instead of the `else` arm (when stepped via Macro
Stepper):

;; test-literal.ss
#lang scheme/base
(require (for-syntax scheme/base
                     "literal.ss"
                     )
         )

(define-syntax (cond/ stx)
  (syntax-case stx ()
    (stx
     (cond* #'stx))
    ))

(cond/ (#f 2) (*else* 5)) ;; error: compile: unbound identifier (and no
#%app syntax transformer is bound) in: if...


But if `cond*` is defined via `begin-for-syntax` as shown in
test-literal2.ss, then it works accordingly:

;; test-literal2.ss
#lang scheme/base
(require (for-syntax scheme/base
                     )
         )
(begin-for-syntax
  (define (cond* stx)
    (syntax-case stx (*else*)
      ((~)
       #`(void))
      ((~ (*else* exp exp2 ...))
       #`(begin (void) exp exp2 ...))
      ((~ (test exp exp2 ...) rest ...)
       #`(if test
             (begin exp exp2 ...)
             #,(cond* #`(cond* #,@#'(rest ...)))))
      ))
  )

(define-syntax (cond/ stx)
  (syntax-case stx ()
    (stx
     (cond* #'stx))
    ))

(cond/ (#f 2) (*else* 5)) ;; works => 5


Any ideas on the differences are appreciated.  Thanks.
yc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100809/6ba8b8cc/attachment.html>

Posted on the users mailing list.