title: Using a syntax macro inside of itself in Racket
body: <p>Apologies if this has been asked before - I'm trying to build a macro similar to <code>struct</code> and I'm a bit stuck.</p>
  
  <p>The basic idea is to be able to provide a hash object to my syntax rule that should then write getters and setters for every key in the hash. For example:</p>
  
  <pre class="lang-lisp prettyprint-override"><code>(hasheq 'name (hasheq 'S "user")
          'isOnline (hasheq 'B #t)
          'bio (hasheq 'M (hasheq 'firstName (hasheq 'S "Sally")
                                  'lastName (hasheq 'S "Wallace"))))
  </code></pre>
  
  <p>Calling my macro:</p>
  
  <pre class="lang-lisp prettyprint-override"><code>(dynamo-model-make-accessors user &lt;my-hash-object&gt;)
  </code></pre>
  
  <p>Should result in the following generated methods:</p>
  
  <pre class="lang-lisp prettyprint-override"><code>user-name
  user-isOnline
  user-bio
  user-bio-firstName
  user-bio-lastName
  </code></pre>
  
  <p>This is what I have so far.</p>
  
  <pre class="lang-lisp prettyprint-override"><code>(define-syntax (dynamo-model-make-accessors stx)
      (syntax-case stx ()
          [(_ prefix fields)
              #`(begin
                      #,@(for/list ([kv (hash-&gt;list (eval (syntax-&gt;datum #'fields)))])
                              (with-syntax* ([key (car kv)]
                                                 [getter (format-id #'prefix "~a-~a" #'prefix #'key)]
                                                  [type (car (hash-keys (cdr kv)))])
                                      (displayln #'getter)
                                      (if (eq? (syntax-&gt;datum #'type) 'M)
                                          (dynamo-model-make-accessors #'prefix (hash-ref (cdr kv) 'M))
                                          #`(define (getter O)
                                              (+ 1 1))))))]))
  </code></pre>
  
  <p>The problem comes in when I try to interpret the nested map. I try to call my syntax rule within itself and I get:</p>
  
  <pre><code>dynamo-model-make-accessors: undefined;
   cannot reference an identifier before its definition
  </code></pre>
  
  <p>How can I recursively call my macro?</p>
  
  <p>EDIT (newest code):</p>
  
  <pre><code>(define-syntax (dynamo-model-make-accessors stx)
      (syntax-parse stx
          [(_dynamo-model-make-accessors prefix fields)
              (define exprs (for/list ([kv (hash-&gt;list (eval #'fields))])
                                      (with-syntax* ([key (car kv)]
                                                         [getter (format-id #'prefix "~a-~a" (eval #'prefix) #'key)]
                                                          [type (car (hash-keys (cdr kv)))]
                                                          [value (hash-ref (cdr kv) (syntax-&gt;datum #'type))])
                                          (displayln #'getter)
                                          (displayln #'type)
                                          (if (eq? (syntax-&gt;datum #'type) 'M)
                                              #`(dynamo-model-make-accessors #'getter value)
                                              #`(define (getter O)
                                                  (+ 1 1))))))
              (with-syntax ([(expr ...) exprs])
                  #'(begin expr ...))]))
  </code></pre>