# Question regarding head patterns in macros generating macros

**URL:** <https://racket.discourse.group/t/question-regarding-head-patterns-in-macros-generating-macros/2088>\
**Category:** Questions & Answers\
**Tags:** question, macro\
**Created:** [July 10, 2023, 6:34pm UTC](https://racket.discourse.group/t/question-regarding-head-patterns-in-macros-generating-macros/2088 "2023-07-10T18:34:39Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jschappel](https://avatars.discourse-cdn.com/v4/letter/j/bbce88/32.png) [@jschappel](https://racket.discourse.group/u/jschappel)\
**Post date:** [July 10, 2023, 6:34pm UTC](https://racket.discourse.group/t/question-regarding-head-patterns-in-macros-generating-macros/2088/1 "2023-07-10T18:34:39Z")

</div>

Hello 👋! I am messing around with racket macros and I have a question regarding macros generating macros. I originally created a simple macro that creates a local binding which allows rackets `define` syntax and limits the arity of functions using the `def` syntax-class. Below is the code:

```scheme
#lang racket
(require racket/local syntax/parse/define (for-syntax syntax/parse racket/list))

(begin-for-syntax
  (define-syntax-class racket-define
    #:literals (define)
    (pattern (define n:id e:expr))
    (pattern (define (n:id params:id ...) body:expr ...+)))
  
  (define-syntax-class (local-func arity)
    (pattern (def (name:id params:id ...) body:expr ...+)
      #:with arg-len (length (syntax->list #'(params ...)))
      #:fail-when (not (equal? (syntax-e #'arg-len) arity))
      (format "Arity mismatch. Expected ~s, but was given ~s" arity (syntax-e #'arg-len)))))
    

(define-syntax (local-arity-1 stx)
  (syntax-parse stx
    [(_ [(~or func:racket-define (~var func (local-func 1))) ...+] body)
     #:fail-when (empty? (syntax->list #`((~? func.name) ...)))
     "Expected at least one 'def' clause"
     #`(local
         ((~? (define (func.name func.params ...) func.body ...)) ...) body)]
    [(_) (raise-syntax-error #f "Expected at least one 'def' clause" stx)]))

(local-arity-1
 [(define x 10)
  (define (add x y) (+ x y))
  (def (add1 x) (+ 1 x))
  (def (sub x y) (- x y)) ;; errors because only one param is allowed
  ]
 (add1 20))

```

I now would like to take this a step further and create a macro that will generate the above macro when given a name and a number representing the arity for the `def`. Currently I have to following:

```scheme
(define-syntax-parse-rule (generate-local-arity macro-name:id num:expr)
  (define-syntax (macro-name stx)
    (syntax-parse stx
      [(_ [(~or func:racket-define (~var func (local-func num))) (... ...+)] body)
       #:fail-when (empty? (syntax->list #`((~? func.name) (... ...))))
       "Expected at least one 'def' clause"
       #`(local
           ((~? (define (func.name func.params (... ...)) func.body (... ...))) (... ...)) body)]
      [(_) (raise-syntax-error #f "Expected at least one 'def' clause" stx)])))

(generate-local-arity local-arity-3 3)

(local-arity-3
 [(define x 10)
  (define (add x y) (+ x y))
  (def (test x y z) (+ x y z))]
 (test 10 10 10))

```

The above works fine when only the `def` syntax class is used, however once I add the `define` syntax-class I get to following error: ` func.name: attribute contains non-syntax value value: #f in: func.name #(1418 9)`. When I ran the code thought the macro stepper I noticed that `~?` is being removed from the generated code which explains why the above error is being outputted. Is there a special syntax that I need to use for nested head patterns?

Any help is appreciated!  
-Josh

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [July 10, 2023, 6:56pm UTC](https://racket.discourse.group/t/question-regarding-head-patterns-in-macros-generating-macros/2088/2 "2023-07-10T18:56:18Z")

</div>

It’s likely because `~?` is associated with the level of the outer macro (`generate-local-arity`), not the inner macro (`macro-name`).

One easy solution is to just escape the entire thing. This is viable in your case since `generate-local-arity` doesn’t have any `...` in the pattern.

```scheme
(define-syntax-parse-rule (generate-local-arity macro-name:id num:expr)
  (...
   (define-syntax (macro-name stx)
     (syntax-parse stx
       [(_ [(~or func:racket-define (~var func (local-func num))) ...+] body)
        #:fail-when (empty? (syntax->list #`((~? func.name) ...)))
        "Expected at least one 'def' clause"
        #`(local
            ((~? (define (func.name func.params ...) func.body ...)) ...) body)]
       [(_) (raise-syntax-error #f "Expected at least one 'def' clause" stx)]))))

```
