<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hello, all you wonderful people. I'm seeing some strange behavior from my macros.<div><br></div><div>So I invoke my <span style="font-family: Courier; "><u>define-sequencer-buttons-info-class</u></span> macro with a bunch of identifiers.</div><div>Its job is to rename the identifiers to add a "-btn" suffix (yes, I use macros to save typing tedium) and then</div><div>invoke my <span style="font-family: Courier; "><u>make-button-contracts</u></span> macro inside of my <font face="Courier" style="text-decoration: underline; ">class/c*</font><font> macro. The job of the former is to expand</font></div><div><font>into a literal form that starts with </font><u style="font-family: Courier; ">init-field-accessor</u> with some extra arguments which is interpreted specially by the latter. </div><div>When I can get <font face="Courier" style="text-decoration: underline; ">make-button-contracts</font><font> to be invoked, it</font> runs correctly, expanding into an argument list starting with <u><font face="Courier">init-field-accessor</font></u>.</div><div><font><br></font></div><div><font><u><font face="Courier">class/c*</font></u> (star at the end) is my macro that expands argument pairs starting with literal symbols <u><font face="Courier">init-field-accessor</font></u> and <font face="Courier" style="text-decoration: underline; ">field-accessor</font><font> </font></font></div><div><font><font>into sets of init, field, and method definitions for mutations of a given name---or passes regular class/c statements through unmodified.</font></font></div><div><font><font><br></font></font></div><div><font><font>The problem is that when Racket is in the <u><font face="Courier">define-sequencer-buttons-info-class</font></u> transformer procedure, it constructs a definition including</font></font></div><div><font><font>an invocation of </font></font><span style="font-family: Courier; "><u>make-button-contracts</u></span> nested inside my invocation of <u style="font-family: Courier; ">class/c*</u>. When <u><font face="Courier">class/c*</font></u> then gets expanded, it passes the </div><div>invocation of <u style="font-family: Courier; ">make-button-contracts</u> through to the standard <u><font face="Courier">class/c</font></u> (without the star)---unmodified----and then starts expanding <u><font face="Courier">class/c </font></u></div><div>without having first expanded <u style="font-family: Courier; ">make-button-contracts</u>. </div><div><br></div><div>It further seems, that <u style="font-family: Courier; ">class/c</u> does not macro-expand any of its arguments, but only matches literal names, so how am I going to get my <u><font face="Courier">make-button-contracts</font></u> to expand</div><div>BEFORE <u><font face="Courier">class/c*</font></u> is expanded? How can I do this with Racket?</div><div><br></div><div>Finally, lest anyone be confused. I use a convention where my s-expression lists that represent immediate procedure applications at that point in the source are surrounded with braces, the ones that are expanded to macros or core, non-procedure functionality are in parentheses, and the rest are in brackets. It's unconventional, but it works for me.</div><div><font><font><br></font></font></div><div><font><font><br></font></font></div><div>Many thanks!</div><div><br></div><div>---Christopher</div><div><font><font><br></font></font></div><div><br></div><div><font face="Courier">; module total-ca-state.rkt (main file) </font><span style="font-family: Courier; ">[ file abbreviated to relevant portions ]</span></div><div><font face="Courier"><br></font></div><div><div><font face="Courier">(define-syntax [make-button-contracts stx]</font></div><div><font face="Courier"> (syntax-case stx []</font></div><div><font face="Courier"> [[_ btn-name ...]</font></div><div><font face="Courier"> (let [[ret </font><span style="font-family: Courier; ">#'(init-field-accessor [btn-name {is-a?/c button-info%}] ...)]]</span></div><div><font face="Courier"> {print ret}</font></div><div><font face="Courier"> ret )]))</font></div><div><font face="Courier"><br></font></div><div><font face="Courier">(define-syntax [define-sequencer-buttons-info-class stx]</font></div><div><font face="Courier"> (syntax-case stx []</font></div><div><font face="Courier"> [[_ name button ...]</font></div><div><font face="Courier"> (let [[buttons </font></div><div><font face="Courier"> (for/list [[btn-id {in-list {syntax->list #'[button ...]}}]]</font></div><div><font face="Courier"> {datum->syntax </font></div><div><font face="Courier"> btn-id</font></div><div><font face="Courier"> {string->symbol</font></div><div><font face="Courier"> {string-append</font></div><div><font face="Courier"> {symbol->string {syntax->datum btn-id}} </font></div><div><font face="Courier"> "-btn" }}</font></div><div><font face="Courier"> btn-id</font></div><div><font face="Courier"> btn-id })]]</font></div><div><font face="Courier"> (define ret</font></div><div><font face="Courier"> #`(define name</font></div><div><font face="Courier"> (class/c*</font></div><div><font face="Courier"> (make-button-contracts #,@buttons) )))</font></div><div><font face="Courier"> {print ret} </font></div><div><font face="Courier"> ret )]))</font></div><div><br></div><div><font face="Courier"> </font></div><div><span style="font-family: Courier; ">(provide sequencer-buttons-info%)</span></div><div><font face="Courier">(define-sequencer-buttons-info-class sequencer-buttons-info%</font></div><div><font face="Courier"> next-user</font></div><div><font face="Courier"> previous-user</font></div><div><span style="font-family: Courier; "> ; ... long list of names (abbreviated) ...</span></div><div><font face="Courier"> lock-user</font></div><div><font face="Courier"> )</font></div><div><br></div></div><div><br></div><div><br></div><div><br></div><div><font face="Courier">; module class-util.rkt (required by the other file) [ truncated to relevant portions ]</font></div><div><font face="Courier"><br></font></div><div><font face="Courier"><div>(define-syntax [class/c* stx]</div><div> (define [flatten lst [times 1]]</div><div> (if {zero? times}</div><div> lst</div><div> {flatten {apply append lst} {sub1 times}} ))</div><div> (syntax-case stx []</div><div> [[_ clause ...]</div><div> (let []</div><div> (define clause-list {syntax->list #'[clause ...]})</div><div> (when {zero? {length clause-list}}</div><div> {raise-syntax-error #f</div><div> "must supply at least one clause"</div><div> stx })</div><div> (define syntax-ret</div><div> {datum->syntax</div><div> stx</div><div> {append</div><div> {list #'class/c}</div><div> {flatten</div><div> (for/list [[clause {in-list clause-list}]]</div><div> (syntax-case clause [init-field-accessor field-accessor]</div><div> [[init-field-accessor sub-clause ...]</div><div> {init-field-accessor* clause} ]</div><div> [[field-accessor sub-clause ...]</div><div> {field-accessor* clause} ]</div><div> </div><div> ; THIS IS WHERE THE CALL TO make-button-contracts IS PASSED THRU TO REGULAR class/c</div><div> [whole-thing {list {list clause}}] )) </div><div> 2 }}</div><div> stx})</div><div> {print syntax-ret}</div><div> syntax-ret )]))</div><div><br></div></font></div></body></html>