[racket] define-syntax-class

From: Nadeem Abdul Hamid (nadeem at acm.org)
Date: Wed Apr 27 23:52:34 EDT 2011

On Wed, Apr 27, 2011 at 11:25 PM, Carl Eastlund <cce at ccs.neu.edu> wrote:
> Modules currently can't define syntax for syntax.  However, you can
> use define-syntax-set from mzlib/etc to define multiple macros at once
> that share local bindings, such as syntax classes.  Since they're
> lexical bindings rather than module bindings, they work just fine.  If
> you want to export them and share them between files, however, you'll
> need to use Sam's suggestion.


That's what I was looking for. Thank you. Here's a complete example
for posterity:


#lang racket/base

(require syntax/parse mzlib/etc
         (for-syntax syntax/parse
                     racket/base)
         )

(define-syntax-set (let let1)

  (define-syntax-class binding
    #:description "binding pair"
    (pattern [var:identifier rhs:expr]))

  (define-syntax-class distinct-bindings
    #:description "sequence of binding pairs"
    (pattern (b:binding ...)
             #:with (var ...) #'(b.var ...)
             #:with (rhs ...) #'(b.rhs ...)
             #:fail-when (check-duplicate-identifier (syntax->list #'(var ...)))
             "duplicate variable name"
             ))

  (define (let/proc stx)
    (syntax-parse stx
       [(let bs:distinct-bindings body:expr)
        #'((λ (bs.var ...) body) bs.rhs ...)]
       [(let)
        (raise-syntax-error #f
                            "expected a sequence of binding pairs and
a body expression"
                            stx #'let)]
       ))

  (define (let1/proc stx)
    (syntax-parse stx
       [(let1 b:binding body:expr)
        #'((λ (b.var) body) b.rhs)]
       [(let1)
        (raise-syntax-error #f
                            "expected a binding pair and a body expression"
                            stx #'let1)]
       ))
  )

(let ([x 1] [y 2]) (+ x y))
(let ((x 4)) (sub1 x))
(let1 (y 2) (add1 y))

#|
All cause errors:
(let1)
(let)
(let x (add1 x))
(let ([x 1]) )
(let ([x 1] [x 2]) (+ x x))
(let ([(x) (f 7)]) (g x x))
(let ([x 1] [y 2]) (+ x x) 4)
|#



Posted on the users mailing list.