[racket] help about a macro that uses a struct define with "make-struct-type"

From: Maurizio Giordano (maurizio.giorda at gmail.com)
Date: Fri Jul 29 08:35:42 EDT 2011


Hi all,

I am not a racket expert, so my problem could be
simply due to my few knwoledge about macros.

My problem is when I am using macros and 
user-defined structs.

I have defined my new structure with "make-struct-type":

; Multiset datatype definition
(define-values (s:mset make-mset mset? mset-ref mset-set!)
   (make-struct-type 'mset #f 1 0 #f
              (list (cons prop:custom-write mset-print))))

I have defined a new reader and writer for this new datatype.
Here you find an example of use of the "mset" datatype.

> (define d1 (make-mset #(1 2 3 4)))
> d1
<1,2,3,4>      ; printed (and read) as a comma-separated set of elements
encolsed by <>
> (mset? d1)   ; the datatype checker

Now I have the following macro:

 (require (for syntax multiset))   ;; import mset? for macro

 (define-syntax (mm stx)
   (syntax-case stx ()                
        [(_ input ...)
         (let* ((l1 (syntax '(input ...)))
                (l2 '(input ...)))
           (map (lambda (x) (print-type x)) l2)   ; assume print-type is
imported for syntax
           (datum->syntax stx `(map (lambda (x) (print-type x)) ,l1)
stx))]))   ; I need this quasiquote/unquote

Where "print-type" is a trivial function that checks the type of "x"
and prints it:

 (define (print-type x) 
   (cond ((symbol? x) (printf "SYM: ~s\n" x))
          ((integer? x) (printf "INT: ~s\n" x))
          ((list? x) (printf "LIST: ~s\n" x))
          ((mset? x) (printf "MSET: ~s\n" x))
         (else (printf "UNK: ~s\n" x))) 

I get the following printout when I call the macro like this:

> (mm 1 x (1 y) < 1, z >)
INT: 1
SYM: x
LIST: (1 y)
UNK: <1, z>
INT: 1
SYM: x
LIST: (1 y)
MSET: <1, z>

It seems that when binding "l2" in the let, the "mset" datatype
is lost, while "l1" in the macro template contains all information.

>From the documentation of "syntax->datum" I have read the following: 
"Returns a datum by stripping the lexical information, source-location
information, properties, and certificates from stx. Inside of pairs,
(immutable) vectors, (immutable) boxes, immutable hash table values (not
keys), and immutable prefab structures, syntax objects are recursively

My structure is not a prefab ... Is this the problem?
How can I preserve the "mset" information in the let binding?

I will appreciate any help.

Thank You.


PS. I read Tom McNulty last post "Advice on a macro for mutating
structs...". Maybe my problem has some similarities with his...

Posted on the users mailing list.