Maurizio, The problem here may be that macros are expanded at a separate phase from the program's run-time. Different phases have different stores, and thus different versions of structure definitions. Your custom reader for the mset datatype produces an mset for use at run-time. The run-time print-type detects this kind of mset, but the compile-time print-type expects a different version of an mset.
Prefab structures would fix this part of the issue, because they do not generate new types, they merely describe a subset of existing types. However, you cannot add a custom reader or writer property to prefab types, so another part of your interface will break. I do not know precisely what you need to detect this type at compile-time for, so I don't have any advice on how to handle this for your purposes. I hope I have at least clarified the behavior you see. Carl Eastlund On Fri, Jul 29, 2011 at 8:35 AM, Maurizio Giordano <[email protected]> wrote: > REPOSTED DUE TO COPY/PASTE ERRORS IN MY ORIGINAL MAIL. > ------------------------------------------------------ > > 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 > #t > > 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))) > 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 > information > 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 > stripped." > > 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. > > Maurizio. > > PS. I read Tom McNulty last post "Advice on a macro for mutating > structs...". Maybe my problem has some similarities with his... > > > _________________________________________________ > For list-related administrative tasks: > http://lists.racket-lang.org/listinfo/users > > _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users

