[plt-scheme] macro questions

From: Ethan Aubin (ethan.aubin at pobox.com)
Date: Sat Jun 5 15:27:15 EDT 2004

; Hi, I'm trying to wrap my head around macros and was wondering if
; any of you could help me write a macro which uses the match
; library. I end up with 'reference to undefined identifier: match'
; errors.

(module boolean-if-helper mzscheme
  (provide (all-defined))

  ;; This helper module is cut down from a bigger program I'm
  ;; writing. It modules defines structures/objects containing syntax
  ;; and annotations, and functions with generate syntax from these
  ;; structures/objects. E.g.

  ;; The next module will define macros and destructure the syntax
  ;; storing it in a structure.
  (define-struct if-info (if-stx true-stx false-stx))
  
  ;; Make a boolean if expression using datum->syntax-object
  (define (make-if desc)
    (let ([if-stx (if-info-if-stx desc)]
          [true-stx (if-info-true-stx desc)]
          [false-stx (if-info-false-stx desc)])

      ; The reference to 'match' here is just constant syntax and in
      ; this module it is not known whether match is a constant
      ; identifier or a macro
      (datum->syntax-object if-stx
        `(match ,if-stx [#t ,true-stx] [#f ,false-stx]))))
  )

(module boolean-if-macro mzscheme
  (provide (all-defined))

  (require-for-syntax 
   ;; ensure structures and transformations using structures are in
   ;; transformer environment
   boolean-if-helper

   ;; ensure match is defined in the transformer enviroment
   (lib "match.ss"))
  
  (define-syntax boolean-if
    (lambda (stx)
      (syntax-case stx ()
        [(_ if-stx true-stx false-stx)
         ;; Evaluated in the transformer environment
         (make-if
          (make-if-info
           (syntax if-stx) (syntax true-stx) (syntax false-stx)))]))))

(module test mzscheme
  (require boolean-if-macro)  
  ; (require (lib "match.ss"))

  ; Without (require (lib "match.ss")) I get a "expand: unbound
  ; variable in module in: match" error
  (display (boolean-if #t 'true 'false)))
(require test)


; So two questions, 1) Is there a better way to structure this? I'd
; ultimately like to write many macros which use the same annotated
; structures and would be much easier if I could split it into several
; helper modules.

; 2) Am I misunderstanding the whats bound on the right-hand side of a
; define-syntax? E.g. in the this modules 'require-for-syntax' doesn't
; work, but 'require' does.

(module boolean-if-simple mzscheme
  (provide (all-defined))
  (require-for-syntax (lib "match.ss"))
  ; (require (lib "match.ss"))
  (define-syntax (bif stx)
    (syntax-case stx ()
     [(_ if-stx then-exp else-exp)
      (syntax
       (match if-stx [#t then-exp] [#f else-exp]))])))
(require boolean-if-simple)
(bif #t 'true 'false)
  
; I'd appreciate any feedback. Thanks - ethan.aubin at pobox.com


Posted on the users mailing list.