[racket] help about a macro that uses a struct define with "make-struct-type"
2011/7/29 Carl Eastlund <cce at ccs.neu.edu>
> On Fri, Jul 29, 2011 at 12:44 PM, Maurizio Giordano
> <maurizio.giorda at gmail.com> wrote:
> > On Fri, 2011-07-29 at 12:20 -0400, Carl Eastlund wrote:
> >>
> >> 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.
> > Now it is perfectly clear to me.
> > thanks a lot.
> >>
> >>
> >> 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.
> > The "templates" I generate at compile-time in the macro are some sort of
> > a syntax tree:
> >
> > An example:
> > the macro (three) inputs: < (1 x), 2 > x 3
> > will generate an hash like this:
> >
> > #hash ((mset . #hash((list . #hash((integer . 1)
> > (symbol . x)))
> > (symbol . x)))
> > (symbol . x)
> > (integer . 3))
> >
> > By using this nested hashtable, the "inject-code" function will
> > produce a (recursive) pattern matchers code to be included in the lambda
> > code generated by the macro. Symbols in the input are not evaluated,
> > they will are considered identifiers to be bound (and unified)
> > during the pattern matching.
> >
> > Therefore, I think I am not using the mset values at compile-time.
> > I simply parse the macro inputs to generate a sort of syntax tree
> > (i.e. the hashtable).
>
> You are not using them as outputs, but you are using them as inputs.
> Even that is problematic, exactly as you have seen. I suggest writing
> a macro using only standard syntax objects containing lists, strings,
> symbols, and numbers for both input and output if at all possible.
>
... unfortunately i need the macro to accept as input a "mset", ricognize
it, and parse recursively the inner mset elements (that can be list,
numbers, or
even other msets).
The hashtable the macro produces at compile time is like
an Abstract Syntax Tree of the macro inputs.
In my new language implementation the mset
is a fundamental data structure, I cannot rely only on standard
syntax objects like lists, strings, etc.
> This will save a lot of trouble. Using hash tables in syntax objects
> can work, but even that brings up some tricky issues. I find it is
> almost always better to consume and produce code that refers to or
> produces complex data types, rather than code actually represented as
> complex data types.
>
Maybe a way could be to generate the hash by making the macro
parsing/processing the list of input syntaxes, rathen than the
inputs themselves. I mean, I can traverse the "syntax" representation
of each input and get the information I need. Maybe it will be more complex,
but it could work.... I don't know.
Another way could be to define a new "match" form, starting from
the one provided by racket. The new "match" should apply also to msets
and ... have other peculiar behaviours (???). Also this way is long.
I will decide which solution to follow.
Thank you, Carl.
If you have any idea, it is welcome.
Cheers,
Maurizio.
PS. Sorry if I was not able to give more details... my implementation is
composed of large-code modules... I am available to send the complete
code to everyone who is interested in collaborating to the project.
long and
>
> --Carl
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110729/f4dc0da5/attachment.html>