[racket] define-syntax-rule/id

From: Laurent (laurent.orseau at gmail.com)
Date: Tue Apr 19 08:46:50 EDT 2011

> I meant in the argument to `datum->syntax'...
>

Ah, great, this is even better.
I can't believe its so small in the end...

For the sake of it, here is what we have now:

#lang racket

(provide define-syntax-rule/id)

;;; By Jon Rafkind (+ tweakings)

;; Like define-syntax-rule, but takes an additional ([id id-rename] ...) set
;; where the id can be used in body,
;; and each id in body is replaced by the result of the id-rename
expression.
(define-syntax (define-syntax-rule/id stx)
  (syntax-case stx ()
    [(_ (name arg ...)
        ([id id-rename] ...)
        body ...)
     #'(define-syntax (name stx2)
         (syntax-case stx2 ()
           [(_ arg ...) ; This comes from above!
            ; We want the defined ids to have the same lexical scope as
            ; the defined macro itself.
            (with-syntax ([id (datum->syntax
                               stx2
                               (string->symbol
                                ; id-rename is an expression that comes from
above.
                                ; it will be replaced by its code in the
first expansion
                                ; (the first syntax-case),
                                ; and this code will be executed in the
second expansion.
                                (let ([arg (syntax-e #'arg)] ...)
                                  id-rename))
                               stx2 stx2 stx2
                               )]
                          ...)
              ; id is correctly bound in body here because
              ; body is replaced by the full expression (containing id)
              ; in this submacro (just like for id-rename).
              #'(begin body ...))]))
       ]))

#| TESTS: |#

; use the macro stepper to see how it is expanded
(define-syntax-rule/id (make-getter-setter xid1 xid2)
  ([getter (format "get-~a-~a" xid1 xid2)]
   [setter (format "set-~a-~a" xid1 xid2)]
   [xchger (format "xch-~a-~a" xid1 xid2)])
  (define (getter) (values xid1 xid2))
  (define (setter v1 v2) (set! xid1 v1) (set! xid2 v2))
  (define (xchger) (setter xid2 xid1))
  )

(define x1 5)
(define x2 6)
(make-getter-setter x1 x2)
(get-x1-x2)
(set-x1-x2 10 11)
(get-x1-x2)
(xch-x1-x2)
(get-x1-x2)

;|#
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110419/987a2e00/attachment.html>

Posted on the users mailing list.