<div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div>Hi there!<br><br>I&#39;m pretty new to Racket, though not the basic concepts of functional programming [1] Maybe I don&#39;t need macros here at all, but it seemed like the right sort of lever when I first started, but now I&#39;m pretty stuck[2] and I don&#39;t understand enough about the macro system yet to be able to figure this out.<br>

<br></div>Basically, I&#39;m trying to make a database migration tool + relational mapper. I&#39;d like to be able to define my tables in an abbreviated Racket syntax and use the definition to generate everything from the create-table SQL scripts, a few, basic CRUD-scripts-for-all-columns to structs that will mirror a full table row when processing the query results.<br>

<br></div>Right now, the table definition looks like this:<br></div><br>(define-table tickets get-all-tickets<br></div> ([ticket_id serial primary-key]<br></div>  [priority int nullable] ;; I believe in making not-null the default case<br>

</div>  [description (varchar max)]<br></div>  [finished_on datetime (default &quot;9999-12-31 23:59:59.999&quot;)]) <br><br></div>And this is pretty easy to parse into some &quot;table&quot; structs that describe everything fairly sufficiently[3]:<br>

<a href="https://gist.github.com/capnmidnight/5506674">https://gist.github.com/capnmidnight/5506674</a><br></div><div><br></div><div>Now, my sticking point is that I don&#39;t want to have explicitly define that &quot;get-all-tickets&quot; identifier. I notice that, in my creating the &quot;column&quot; struct, I&#39;ve received a number of procedures for the constructor and field accessors, all given a prefix of &quot;column&quot; for their identifier. So at first glance, it seems like there are forms like struct that are capable of dynamically defining identifiers.<br>

<br>So, I stepped into the definition for struct and tried to make sense of it, but the best I could figure out was that struct used syntax-case instead of syntax-rules. It was a bit of a hair-ball for me, I couldn&#39;t suss out the cross references, and at least at this late of an hour I&#39;m having trouble understanding the documentation on syntax-case.<br>

<br></div><div>Specifically, I tried to do something like:<br><br>(define-syntax (double-define stx)<br>  (syntax-case stx (double-define)<br>    [(_ id val1 val2)<br>     #`(begin (define id-1 val1)<br>              (define id-2 val2))]))<br>

<br>(double-define id 3 7)<br>(displayln id-1) <span style="color:rgb(255,0,0)">;; error &quot;id-1 unbound identifier&quot;</span><br>(displayln id-2)<br><br></div><div>I then tried something like:<br><br>(define-syntax (double-define stx)<br>

  (syntax-case stx (double-define)<br>    [(_ id val1 val2)<br>     (with-syntax ([id-1 #&#39;(string-&gt;symbol (format &quot;~a-1&quot; id))] <span style="background-color:rgb(255,255,255)"><span style="color:rgb(255,0,0)">;; error &quot;define: not an identifier, identifier with default, or keyword for procedure argument</span></span>&quot;<br>

                   [id-2 #&#39;(string-&gt;symbol (format &quot;~a-2&quot; id))])<br>       #&#39;(begin (define id-1 val1)<br>                (define id-2 val2)))]))<br><br>(double-define id 3 7)<br>(displayln id-1)<br>
(displayln id-2)<br>
</div><div><br></div><div>Clearly, not correct.<br></div><div><br></div><div>I could make the table struct into a table class and then just define a get-all method that does what I want, but that kind of feels like giving up and I&#39;m more interested in using this to learn more about using macros, as it has already done for me.<br>

<br><br><br></div><div>[1] Functional C# is something of a job safety program of mine :P<br></div><div><br>[2] i.e. been banging my head against the desk for the last 6 hours. I have gotten pretty comfortable with syntax-rules though, so it wasn&#39;t a complete waste.<br>

<br>[3] This isn&#39;t the final form, but I&#39;m just pushing some code around to try to 
get the basic concepts working. For example, the get-all-tickets 
procedure wouldn&#39;t just return the query, it&#39;d eventually execute it and return the results.<br></div></div></div></div></div>