<div dir="ltr"><div>Hello,</div><div><br></div><div>First the short question: is there a way that user code can set some sort of in-effect global variable to determine how a library macro will expand? The problem I have is there doesn't seem to be a way to combine the concepts of parameters/globals and transformer environments.</div>
<div><br></div><div><div>Long part in case it's not clear why I'm trying to do this or if someone knows a better way (I was hoping writing this would cause me to figure it out and avoid having to ask the question, as is usually the case. It did not work.):</div>
<div><br></div><div>I am attempting to define a library macro. This macro's expansion should be based on the user's global parameterization of it. It is a macro to create an association list between "commands" and functions for keyboard input (or any input). The association list looks like this for example:</div>
<div><br></div><div>'([left (lambda (params ...) (code-to-move-left))]</div><div> [right (lambda (params ...) (code-to-move-right))])</div><div><br></div><div>where there is some config file like:</div><div><br></div>
<div>a = left</div><div>d = right</div><div><br></div><div>that associates keys to commands, and ultimately the library associates keys to code by combining the two associations transitively.</div><div><br></div><div>The macro named "commands" to build the first table is written to save on the duplicate "(lambda (param ...)" portion, so the user code building the alist goes like this:</div>
<div><br></div><div>(commands (params ...)</div><div> (left (code-to-move-left))</div><div> (right (code-to-move-right)))</div><div><br></div><div>The problem comes in when the user does not define commands all at once. Two calls to the "commands" macro require using the same parameter list, since there is a top-level "run-input" function that checks if a key is down and runs the associated function, passing in the generic parameter set (regardless of which / if any keys that are down). So I want to have "commands" be defined something like this:</div>
<div><br></div><div>(define-syntax (commands stx)<br> (syntax-case stx ()<br> [(_ (c f) ...)<br> #`(list (cons (symbol->string 'c)<br> (ë #,input-params f))<br> ...)]))</div><div>
<br></div><div>Where input-params is bound to the syntax of the parameter list. The usage is ideally:</div><div><br></div><div>(define users-constant #'(state delta-time))</div><div><br></div><div>(syntax-paramterize or set! or whatever on input-params to users-constant</div>
<div> (commands</div><div> (left (move-left! state (* speed delta-time)))</div><div> (right (move-right! etc...</div><div><br></div><div>expanding into:</div><div><br></div><div>'([left (lambda (state delta-time) (move-left! state (* speed delta-time)))]</div>
<div> [right etc...])</div><div><br></div><div>But I can't figure it out.</div><div><br></div><div>By placing this hypothetical extension of the library code into the user code, I can write this as a wrapper macro on "commands" that shares the user's constant piece of syntax using datum->syntax:</div>
<div><br></div><div>(define-for-syntax (input-params stx)</div><div> (datum->syntax stx '(state delta-time)))</div><div><br></div><div>(define-syntax (cmds stx)</div><div> (syntax-case stx ()</div><div> [(_ body ...)</div>
<div> #`(commands #,(input-params stx)</div><div> body ...)]))</div><div><br></div><div>and now all calls to cmds will share a single parameter list as required. But this is weak because this code will be the same for every user except the actual parameter list embedded within input-params definition, so I'm looking for a way to get the above functionality into the library, yet still have the user define the "'(state delta-time)" portion themselves. Basically copy paste the "cmds" definition into the library, and then I would just need "set!-for-syntax input-params '(state delta-time)" to be possible.</div>
<div><br></div><div>One day I hope to have a Racket + OpenGL answer to something like XNA. That day is not today.</div></div></div>