[plt-scheme] A silly meta-macro problem...

From: Taylor Campbell (campbell at evdev.ath.cx)
Date: Mon Jan 13 14:43:21 EST 2003

Jerzy Karczmarczuk wrote:

 >  [snip]

You're making this -WAY- too complicated.  'require-for-syntax' is only
for the use of evaluating the macro expander; it has nothing to do with
the expression that a macro expands to.

In fact, it's quite simple how to do that sort of thing; you don't even
need to enclose it in a module.

;; For defining 'something%'.
(require (lib "class.ss"))

(define something%
   (class object%
     (public foo bar baz)
     (init-field quux zot)

     ;; Some silly example methods.
     (define (foo a) (list 'foo quux zot a))
     (define (bar a b) (list 'bar quux zot a b))
     (define (baz a b . c) (list* 'baz quux zot a b c))

     (super-instantiate ())))

;; While this looks complicated, that's mostly because of the
;; introduction of the '?name:' identifier.
(define-syntax (define-something stx)
   (syntax-case stx ()
     ((_ ?name ?init-param ...)
      ;; Get 'foobar:' to not be hygienically changed to something else.
      (with-syntax ((?name:
               ;; PLT ought to have more operations that operate directly
               ;; on syntax objects; the lack of this is the cause
               ;; of the ugliness of all this extra coercion.
                     (datum->syntax-object
                      stx
                      (string->symbol
                       (string-append
                        (symbol->string
                         (syntax-object->datum (syntax ?name)))
                        ":")))))
        (syntax
         (begin
           (define ?name (make-object something% ?init-param ...))
           (define-syntax ?name:
             (syntax-rules ()
                ;; The (... ...) bit makes it not be considered ellipsis
                ;; in the expansion expression for 'define-something'.
               ((_ ?method ?method-param (... ...))
                (send ?name ?method ?method-param (... ...))))))))))

(define-something foobar "quux" "zot")
(foobar: foo "a") ;; ==> (foo "quux" "zot" "a")
(foobar: baz "a" 'b '(c)) ;; ==> (baz "quux" "zot" "a" b c)




Posted on the users mailing list.