On Fri, Jul 29, 2011 at 12:05 PM, Maurizio Giordano <[email protected]> wrote: > Hi Carl, > > On Fri, 2011-07-29 at 11:09 -0400, Carl Eastlund wrote: >> 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. > Ok. the difference between the two phases is now clear to me... > what is not still clear is: > 1) at compile-time the "mset?" checker function is known... otherwise I > would see an "undefined mset?" > (in fact I specify a (require (for-syntax multiset)), where multiset is > a module implementing the new datastructure). > 2) always at compile-time, the (mset? < ... >) expression returns #f. > So it seems to me that at compile-time the struct object has lost some > information.
There is one module called "multiset", but all of its definitions are executed twice because your program uses them in two different phases: once at run-time and once at compile-time. That means there are two different mset types with two different constructors and two different mset? predicates. Call the run-time versions mset.1 and mset?.1, and the compile-time versions mset.2 and mset?.2. Similarly, you have print-type.1 and print-type.2 at run-time and compile-time. Your custom reader produces an mset.1 value. Your macro calls print-type.2 which checks mset?.2, and mset?.2 produces #false when given an mset.1 value. The code your macro produces, however, calls print-type.1, which checks mset?.1, and that produces #true (I'm using the new long-form names of #f and #t for readability). So no information is being lost -- it's just that there are two versions of everything running around, and they cannot be mixed and matched. >> 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. > Yes, you are right... I would like to keep my custom reader/writer. > So I cannot use prefab structs. >> >> 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. > > At compile-time I would like to process the macro inputs (of course also > <...> structs) to generate some pattern-matching "templates" to be > injected in the code the macro generates and execute at runtime. > Something like this: > > (define-syntax (mm stx) > (syntax-case stx () > [(_ input ...) > (let* ((l1 (syntax '(input ...))) > (templates (... process/and/recognize msets in l1 ...))) > (datum->syntax stx > `(lambda (x) ,(inject-code patterns)) stx))])) > > Therefore, what I really need is that the new data structure is parsed > (and its type cecked) at compile time. > > Thanks, > Cheers, > Maurizio. Are you sure you want to put mset values in as literal syntax? That leads to all sorts of odd behavior -- for instance, the contents of those msets will need to be syntax at compile-time if they are to contain expressions, but non-syntax at run-time if they are to contain useful values. The expansion system will not do this plumbing for you. You'll get a lot more "bang for your buck" if you instead just use a match expander as both a pattern to recognize msets and a constructor to build them. This avoids all issues of crossing phase boundaries, because the compile-time code acts entirely by recognizing identifier bindings, and does not have to know about the representation of msets at all. --Carl _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users

