Is there an existing Racket analogue for the "define-type" language form from the PLAI text? Is there a quick way for me to just (require-syntax define-type) so I can use it in my otherwise purely-Racket programs? Or perhaps, is there a way for me to look at the original syntax definitions so I can puzzle over how it's done?<div>
<br></div><div>Assuming there isn't, I've been trying to write a macro to just implement define-type (or something like it) myself, and I've run into a question about macros.</div><div><br></div><div>So say I want to write a macro to expand the following:</div>
<div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><div><font face="'trebuchet ms', sans-serif">(define-type expr</font></div></div><div><div><font face="'trebuchet ms', sans-serif"> [num (val) (integer?)]</font></div>
</div><div><div><font face="'trebuchet ms', sans-serif"> [sum (lhs rhs) (expr? expr?)])</font></div></div><div><font face="'trebuchet ms', sans-serif"><br></font></div><div><font face="'trebuchet ms', sans-serif">; expands into</font></div>
<div><div><font face="'trebuchet ms', sans-serif">(begin</font></div><div><font face="'trebuchet ms', sans-serif"> (struct expr ())</font></div><div><font face="'trebuchet ms', sans-serif"> (struct num expr (val) #:guard <<i>some guard function</i>>)</font></div>
<div><font face="'trebuchet ms', sans-serif"> (struct sum expr (lhs rhs) #:guard <some<i> guard function</i>>))</font></div></div></blockquote><div><br></div><div>I have two define-syntaxes that look like</div>
<div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><div><font face="'trebuchet ms', sans-serif">(define-syntax define-type</font></div></div><div><div><font face="'trebuchet ms', sans-serif"> (syntax-rules ()</font></div>
</div><div><div><font face="'trebuchet ms', sans-serif"> [(define-type id subtypes ...) </font></div><div><font face="'trebuchet ms', sans-serif"> (begin</font></div></div><div><div><font face="'trebuchet ms', sans-serif"> (struct id ())</font></div>
</div><div><div><font face="'trebuchet ms', sans-serif"> (define-subtypes id subtypes ...))]))</font></div></div><div><div><font face="'trebuchet ms', sans-serif"><br></font></div></div><div><div><font face="'trebuchet ms', sans-serif">(define-syntax define-subtypes</font></div>
</div><div><div><font face="'trebuchet ms', sans-serif"> (syntax-rules ()</font></div></div><div><div><font face="'trebuchet ms', sans-serif"> [(define-subtypes supertype-id) #t] ; base case</font></div>
</div><div><div><font face="'trebuchet ms', sans-serif"> [(define-subtypes supertype-id type1 type2 ...)</font></div><div><font face="'trebuchet ms', sans-serif"> (<font color="#cc0000">values </font></font></div>
</div><div><div><font face="'trebuchet ms', sans-serif"> (define-subtype type1 supertype-id) ; define-subtype is defined elsewhere, and works</font></div></div><div><div><font face="'trebuchet ms', sans-serif"> (define-subtypes supertype-id type2 ...))]))</font></div>
</div></blockquote><div><br>I get an interesting error along the lines of </div><div><br></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><font face="'courier new', monospace">define-values: illegal use (not at top-level) in: (define-values...</font></div>
</blockquote><div><br></div><div>I'm guessing it has something to do with the rule that a define-syntax isn't allowed to change the surrounding lexical scope, and hence the use of <font color="#cc0000">values</font> is not allowed (even though here it was invoked by another define-syntax...). But seeing as this is my first foray into macro territory, I can't be too sure. Can someone verify or deny my suspicion?</div>
<div><br></div><div>Admittedly, my desire to use <font face="'courier new', monospace">values </font>instead of further nesting <font face="'courier new', monospace">begin </font>is arbitrary, but it would help for me to understand why Racket dislikes the use of <font face="'courier new', monospace">values </font>there, and whether there is a way for me to expand it to a single <font face="'courier new', monospace">begin </font>expression. Perhaps some trickery with turning a list into a <font face="'courier new', monospace">values </font>expression, and then doing that outside of the <font face="'courier new', monospace">(define-syntax define-subtype) </font>expression? Is there a "safe" way to ensure that only <font face="'courier new', monospace">define-type</font> may call <font face="'courier new', monospace">define-subtype</font>, and then the nested <font face="'courier new', monospace">define-subtype</font> is free to break the normal restrictions on syntax definitions?</div>
<div><br></div><div>On another note, is there a nice way for me to print out the literal expansion performed by define-syntax?</div><div><br></div><div>I appreciate the knowledge!</div><div><br></div><div>Jeremy<br>
</div>